summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore5
-rw-r--r--configure.in9
-rw-r--r--include/m_string.h2
-rw-r--r--include/my_handler.h22
-rw-r--r--include/queues.h61
-rw-r--r--include/thr_alarm.h6
-rw-r--r--include/thr_lock.h4
-rw-r--r--libmysqld/CMakeLists.txt9
-rw-r--r--libmysqld/Makefile.am6
-rw-r--r--mysql-test/Makefile.am4
-rw-r--r--mysql-test/include/check_no_concurrent_insert.inc2
-rw-r--r--mysql-test/include/common-tests.inc2
-rw-r--r--mysql-test/include/index_merge2.inc2
-rw-r--r--mysql-test/include/mix1.inc3
-rw-r--r--mysql-test/include/mrr_tests.inc118
-rw-r--r--mysql-test/include/world.inc5343
-rw-r--r--mysql-test/include/world_schema.inc25
-rw-r--r--mysql-test/include/world_schema1.inc18
-rwxr-xr-xmysql-test/mysql-test-run.pl4
-rw-r--r--mysql-test/r/archive_gis.result2
-rw-r--r--mysql-test/r/compare.result2
-rw-r--r--mysql-test/r/compress.result58
-rw-r--r--mysql-test/r/create.result2
-rw-r--r--mysql-test/r/ctype_collate.result12
-rw-r--r--[-rwxr-xr-x]mysql-test/r/ctype_eucjpms.result0
-rw-r--r--mysql-test/r/ctype_utf8.result2
-rw-r--r--mysql-test/r/derived.result10
-rw-r--r--mysql-test/r/distinct.result18
-rw-r--r--mysql-test/r/explain.result24
-rw-r--r--mysql-test/r/func_concat.result2
-rw-r--r--mysql-test/r/func_gconcat.result4
-rw-r--r--mysql-test/r/func_group.result6
-rw-r--r--mysql-test/r/func_group_innodb.result4
-rw-r--r--mysql-test/r/func_in.result52
-rw-r--r--mysql-test/r/func_str.result4
-rw-r--r--mysql-test/r/gis.result2
-rw-r--r--mysql-test/r/greedy_optimizer.result292
-rw-r--r--mysql-test/r/group_by.result19
-rw-r--r--mysql-test/r/group_min_max.result6
-rw-r--r--mysql-test/r/heap.result2
-rw-r--r--mysql-test/r/heap_btree.result35
-rw-r--r--mysql-test/r/heap_hash.result35
-rw-r--r--mysql-test/r/index_merge_myisam.result101
-rw-r--r--mysql-test/r/information_schema.result4
-rw-r--r--mysql-test/r/innodb.result6
-rw-r--r--mysql-test/r/innodb_mrr.result662
-rw-r--r--mysql-test/r/innodb_mrr_cpk.result148
-rw-r--r--mysql-test/r/join.result58
-rw-r--r--mysql-test/r/join_cache.result6125
-rw-r--r--mysql-test/r/join_nested.result96
-rw-r--r--mysql-test/r/join_nested_jcl6.result1918
-rw-r--r--mysql-test/r/join_outer.result57
-rw-r--r--mysql-test/r/join_outer_innodb.result2
-rw-r--r--mysql-test/r/join_outer_jcl6.result1553
-rw-r--r--mysql-test/r/key_cache.result6
-rw-r--r--mysql-test/r/key_diff.result2
-rw-r--r--[-rwxr-xr-x]mysql-test/r/lowercase_mixed_tmpdir_innodb.result0
-rw-r--r--mysql-test/r/maria_mrr.result405
-rw-r--r--mysql-test/r/merge.result2
-rw-r--r--mysql-test/r/mix2_myisam.result8
-rw-r--r--mysql-test/r/myisam.result18
-rw-r--r--mysql-test/r/myisam_mrr.result510
-rw-r--r--mysql-test/r/named_pipe.result56
-rw-r--r--mysql-test/r/negation_elimination.result2
-rw-r--r--mysql-test/r/null.result6
-rw-r--r--mysql-test/r/null_key.result26
-rw-r--r--mysql-test/r/optimizer_switch.result99
-rw-r--r--mysql-test/r/order_by.result35
-rw-r--r--mysql-test/r/partition_pruning.result10
-rw-r--r--mysql-test/r/pool_of_threads.result58
-rw-r--r--mysql-test/r/ps.result7
-rw-r--r--mysql-test/r/ps_1general.result4
-rw-r--r--mysql-test/r/ps_2myisam.result2
-rw-r--r--mysql-test/r/range.result80
-rw-r--r--mysql-test/r/row.result2
-rw-r--r--mysql-test/r/select.result124
-rw-r--r--mysql-test/r/select_jcl6.result4811
-rw-r--r--mysql-test/r/select_pkeycache.result124
-rw-r--r--mysql-test/r/select_safe.result8
-rw-r--r--mysql-test/r/shm.result56
-rw-r--r--mysql-test/r/sp-threads.result2
-rw-r--r--mysql-test/r/sp.result10
-rw-r--r--mysql-test/r/ssl.result58
-rw-r--r--mysql-test/r/ssl_compress.result58
-rw-r--r--mysql-test/r/subselect.result453
-rw-r--r--mysql-test/r/subselect2.result10
-rw-r--r--mysql-test/r/subselect3.result509
-rw-r--r--mysql-test/r/subselect3_jcl6.result1449
-rw-r--r--mysql-test/r/subselect4.result313
-rw-r--r--mysql-test/r/subselect_cache.result3312
-rw-r--r--mysql-test/r/subselect_mat.result1346
-rw-r--r--mysql-test/r/subselect_no_mat.result4995
-rw-r--r--mysql-test/r/subselect_no_opts.result4989
-rw-r--r--mysql-test/r/subselect_no_semijoin.result4989
-rw-r--r--mysql-test/r/subselect_notembedded.result1
-rw-r--r--mysql-test/r/subselect_nulls.result114
-rw-r--r--mysql-test/r/subselect_partial_match.result65
-rw-r--r--mysql-test/r/subselect_sj.result1122
-rw-r--r--mysql-test/r/subselect_sj2.result726
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result740
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result1165
-rw-r--r--mysql-test/r/table_elim.result54
-rw-r--r--mysql-test/r/table_elim_debug.result2
-rw-r--r--mysql-test/r/type_date.result4
-rw-r--r--mysql-test/r/type_datetime.result18
-rw-r--r--mysql-test/r/union.result6
-rw-r--r--mysql-test/r/view.result20
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_row.test2
-rw-r--r--mysql-test/suite/funcs_1/datadict/processlist_val.inc10
-rw-r--r--mysql-test/suite/handler/aria.result128
-rw-r--r--mysql-test/suite/handler/handler.inc76
-rw-r--r--mysql-test/suite/handler/innodb.result128
-rw-r--r--mysql-test/suite/handler/myisam.result128
-rw-r--r--mysql-test/suite/innodb/r/innodb.result6
-rw-r--r--mysql-test/suite/innodb/r/innodb_gis.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result101
-rw-r--r--mysql-test/suite/innodb/t/innodb_mysql.test72
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb.result4
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_gis.result2
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_mysql.result9
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb.test6
-rw-r--r--mysql-test/suite/maria/r/maria.result14
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/README.txt29
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug36981.result9
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug40992.result15
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41029.result34
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb-innodb.result0
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb.result1108
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1.result1108
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb-innodb.result0
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb.result1107
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2.result1107
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb-innodb.result0
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb.result984
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3.result984
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb-innodb.result0
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb.result984
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4.result984
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996.result8
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug42991.result252
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug43101.result31
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug43249.result11
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug43360.result44
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug43448.result30
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result98
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug43618.result57
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result199
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result100
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug49129.result39
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug36981.test14
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug40992.test21
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41029-master.opt1
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41029.test44
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1-innodb.test487
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1.test487
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2-innodb.test486
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2.test486
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3-innodb.test363
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3.test363
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4-innodb.test363
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4.test363
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996.test14
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug42991.test248
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug43101.test41
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug43249.test17
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug43360.test44
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug43448.test58
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug43617.test86
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug43618.test49
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug45219.test183
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug45221.test97
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug49129.test34
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/disabled.def7
-rw-r--r--mysql-test/suite/parts/r/partition_special_innodb.result12
-rw-r--r--mysql-test/suite/parts/r/partition_special_myisam.result8
-rw-r--r--mysql-test/suite/pbxt/r/derived.result14
-rw-r--r--mysql-test/suite/pbxt/r/distinct.result16
-rw-r--r--mysql-test/suite/pbxt/r/explain.result2
-rw-r--r--mysql-test/suite/pbxt/r/func_group.result4
-rw-r--r--mysql-test/suite/pbxt/r/greedy_optimizer.result292
-rw-r--r--mysql-test/suite/pbxt/r/group_by.result6
-rw-r--r--mysql-test/suite/pbxt/r/group_min_max.result4
-rw-r--r--mysql-test/suite/pbxt/r/heap.result2
-rw-r--r--mysql-test/suite/pbxt/r/join.result6
-rw-r--r--mysql-test/suite/pbxt/r/join_nested.result84
-rw-r--r--mysql-test/suite/pbxt/r/join_outer.result14
-rw-r--r--mysql-test/suite/pbxt/r/key_cache.result2
-rw-r--r--mysql-test/suite/pbxt/r/negation_elimination.result2
-rw-r--r--mysql-test/suite/pbxt/r/null.result2
-rw-r--r--mysql-test/suite/pbxt/r/null_key.result26
-rw-r--r--mysql-test/suite/pbxt/r/order_by.result8
-rw-r--r--mysql-test/suite/pbxt/r/partition_pruning.result6
-rw-r--r--mysql-test/suite/pbxt/r/ps_1general.result4
-rw-r--r--mysql-test/suite/pbxt/r/range.result30
-rw-r--r--mysql-test/suite/pbxt/r/select.result42
-rw-r--r--mysql-test/suite/pbxt/r/select_safe.result8
-rw-r--r--mysql-test/suite/pbxt/r/subselect.result120
-rw-r--r--mysql-test/suite/pbxt/r/union.result4
-rw-r--r--mysql-test/suite/pbxt/t/lock_multi.test16
-rw-r--r--mysql-test/suite/pbxt/t/subselect.test17
-rw-r--r--mysql-test/suite/sys_vars/r/concurrent_insert_func.result4
-rw-r--r--mysql-test/suite/sys_vars/t/concurrent_insert_func.test4
-rw-r--r--mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test4
-rw-r--r--mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test2
-rw-r--r--mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test8
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result19
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_innodb.result26
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result28
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test20
-rw-r--r--mysql-test/t/ctype_cp1251.test1
-rw-r--r--mysql-test/t/heap_btree.test16
-rw-r--r--mysql-test/t/heap_hash.test17
-rw-r--r--mysql-test/t/index_merge_myisam.test74
-rw-r--r--mysql-test/t/innodb_mrr.test366
-rw-r--r--mysql-test/t/innodb_mrr_cpk.test137
-rw-r--r--mysql-test/t/insert_notembedded.test2
-rw-r--r--mysql-test/t/join.test19
-rw-r--r--mysql-test/t/join_cache.test2763
-rw-r--r--mysql-test/t/join_nested.test2
-rw-r--r--mysql-test/t/join_nested_jcl6.test101
-rw-r--r--mysql-test/t/join_outer.test2
-rw-r--r--mysql-test/t/join_outer_jcl6.test17
-rw-r--r--mysql-test/t/lock_multi.test22
-rw-r--r--mysql-test/t/maria_mrr.test127
-rw-r--r--mysql-test/t/merge-big.test2
-rw-r--r--mysql-test/t/multi_update.test8
-rw-r--r--mysql-test/t/myisam_mrr.test220
-rw-r--r--mysql-test/t/optimizer_switch.test113
-rw-r--r--mysql-test/t/order_by.test6
-rw-r--r--mysql-test/t/ps.test5
-rw-r--r--mysql-test/t/query_cache_28249.test4
-rw-r--r--mysql-test/t/select_jcl6.test17
-rw-r--r--mysql-test/t/sp_notembedded.test2
-rw-r--r--mysql-test/t/sp_sync.test2
-rw-r--r--mysql-test/t/status.test2
-rw-r--r--mysql-test/t/subselect.test669
-rw-r--r--mysql-test/t/subselect3.test394
-rw-r--r--mysql-test/t/subselect3_jcl6.test17
-rw-r--r--mysql-test/t/subselect4.test269
-rw-r--r--mysql-test/t/subselect_cache.test1616
-rw-r--r--mysql-test/t/subselect_mat.test990
-rw-r--r--mysql-test/t/subselect_no_mat.test11
-rw-r--r--mysql-test/t/subselect_no_opts.test9
-rw-r--r--mysql-test/t/subselect_no_semijoin.test8
-rw-r--r--mysql-test/t/subselect_notembedded.test5
-rw-r--r--mysql-test/t/subselect_nulls.test94
-rw-r--r--mysql-test/t/subselect_partial_match.test72
-rw-r--r--mysql-test/t/subselect_sj.test986
-rw-r--r--mysql-test/t/subselect_sj2.test904
-rw-r--r--mysql-test/t/subselect_sj2_jcl6.test18
-rw-r--r--mysql-test/t/subselect_sj_jcl6.test45
-rw-r--r--mysql-test/t/trigger_notembedded.test2
-rw-r--r--[-rwxr-xr-x]mysql-test/t/windows.test0
-rw-r--r--mysys/queues.c635
-rw-r--r--mysys/safemalloc.c4
-rw-r--r--mysys/thr_alarm.c203
-rw-r--r--mysys/thr_lock.c11
-rw-r--r--scripts/mysql_install_db.sh12
-rw-r--r--[-rwxr-xr-x]sql/CMakeLists.txt13
-rw-r--r--sql/Makefile.am17
-rw-r--r--sql/event_db_repository.cc8
-rw-r--r--sql/event_queue.cc46
-rw-r--r--[-rwxr-xr-x]sql/event_scheduler.cc2
-rw-r--r--sql/events.cc4
-rw-r--r--sql/field.cc16
-rw-r--r--sql/field.h16
-rw-r--r--sql/field_conv.cc13
-rw-r--r--sql/filesort.cc27
-rw-r--r--sql/ha_ndbcluster.cc3
-rw-r--r--sql/ha_ndbcluster.h10
-rw-r--r--sql/ha_partition.cc27
-rw-r--r--sql/handler.cc154
-rw-r--r--sql/handler.h309
-rw-r--r--sql/item.cc811
-rw-r--r--sql/item.h241
-rw-r--r--sql/item_buff.cc24
-rw-r--r--sql/item_cmpfunc.cc279
-rw-r--r--sql/item_cmpfunc.h48
-rw-r--r--sql/item_func.cc37
-rw-r--r--sql/item_func.h9
-rw-r--r--sql/item_row.cc14
-rw-r--r--sql/item_row.h1
-rw-r--r--sql/item_subselect.cc2737
-rw-r--r--sql/item_subselect.h662
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/item_sum.h9
-rw-r--r--sql/key.cc332
-rw-r--r--sql/lock.cc305
-rw-r--r--sql/log.cc4
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/multi_range_read.cc1696
-rw-r--r--sql/multi_range_read.h623
-rw-r--r--sql/mysql_priv.h113
-rw-r--r--sql/mysqld.cc116
-rw-r--r--sql/net_serv.cc42
-rw-r--r--sql/opt_index_cond_pushdown.cc399
-rw-r--r--sql/opt_range.cc819
-rw-r--r--sql/opt_range.h149
-rw-r--r--sql/opt_range_mrr.cc332
-rw-r--r--sql/opt_subselect.cc3502
-rw-r--r--sql/opt_subselect.h369
-rw-r--r--sql/opt_table_elimination.cc18
-rw-r--r--sql/procedure.h4
-rw-r--r--sql/protocol.cc3
-rw-r--r--sql/set_var.cc46
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sp_rcontext.cc2
-rw-r--r--sql/sql_array.h72
-rw-r--r--sql/sql_base.cc111
-rw-r--r--sql/sql_class.cc101
-rw-r--r--sql/sql_class.h259
-rw-r--r--sql/sql_cursor.cc3
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_delete.cc1
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_expression_cache.cc277
-rw-r--r--sql/sql_expression_cache.h84
-rw-r--r--sql/sql_handler.cc620
-rw-r--r--sql/sql_handler.h61
-rw-r--r--sql/sql_insert.cc24
-rw-r--r--sql/sql_join_cache.cc4449
-rw-r--r--sql/sql_join_cache.h1407
-rw-r--r--sql/sql_lex.cc94
-rw-r--r--sql/sql_lex.h14
-rw-r--r--sql/sql_lifo_buffer.h342
-rw-r--r--sql/sql_load.cc17
-rw-r--r--sql/sql_parse.cc55
-rw-r--r--sql/sql_plugin.cc2
-rw-r--r--sql/sql_prepare.cc62
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_select.cc4135
-rw-r--r--sql/sql_select.h513
-rw-r--r--sql/sql_show.cc19
-rw-r--r--sql/sql_string.cc18
-rw-r--r--sql/sql_string.h57
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_test.cc70
-rw-r--r--sql/sql_trigger.cc8
-rw-r--r--sql/sql_trigger.h2
-rw-r--r--sql/sql_union.cc40
-rw-r--r--sql/sql_update.cc13
-rw-r--r--sql/sql_view.cc4
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/structs.h24
-rw-r--r--sql/table.cc174
-rw-r--r--sql/table.h34
-rw-r--r--sql/uniques.cc8
-rw-r--r--storage/federatedx/ha_federatedx.cc9
-rw-r--r--storage/heap/ha_heap.cc15
-rw-r--r--storage/heap/hp_create.c8
-rw-r--r--storage/heap/hp_hash.c58
-rw-r--r--storage/innobase/handler/ha_innodb.cc1
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc2
-rw-r--r--storage/maria/ha_maria.cc115
-rw-r--r--storage/maria/ha_maria.h37
-rw-r--r--storage/maria/ma_extra.c9
-rw-r--r--storage/maria/ma_ft_boolean_search.c13
-rw-r--r--storage/maria/ma_ft_nlq_search.c4
-rw-r--r--storage/maria/ma_key.c64
-rw-r--r--storage/maria/ma_open.c4
-rw-r--r--storage/maria/ma_rkey.c24
-rw-r--r--storage/maria/ma_rnext.c9
-rw-r--r--storage/maria/ma_rnext_same.c9
-rw-r--r--storage/maria/ma_sort.c6
-rw-r--r--storage/maria/maria_def.h9
-rw-r--r--storage/maria/maria_pack.c36
-rw-r--r--storage/myisam/ft_boolean_search.c14
-rw-r--r--storage/myisam/ft_nlq_search.c4
-rw-r--r--storage/myisam/ha_myisam.cc131
-rw-r--r--storage/myisam/ha_myisam.h30
-rw-r--r--storage/myisam/mi_extra.c6
-rw-r--r--storage/myisam/mi_key.c57
-rw-r--r--storage/myisam/mi_open.c35
-rw-r--r--storage/myisam/mi_rkey.c92
-rw-r--r--storage/myisam/mi_rnext.c40
-rw-r--r--storage/myisam/mi_rnext_same.c9
-rw-r--r--storage/myisam/mi_rprev.c38
-rwxr-xr-xstorage/myisam/mi_test_all.sh1
-rw-r--r--storage/myisam/myisamdef.h6
-rw-r--r--storage/myisam/myisampack.c36
-rw-r--r--storage/myisam/sort.c6
-rw-r--r--storage/myisammrg/myrg_queue.c4
-rw-r--r--storage/myisammrg/myrg_rnext.c4
-rw-r--r--storage/myisammrg/myrg_rnext_same.c4
-rw-r--r--storage/myisammrg/myrg_rprev.c4
-rw-r--r--storage/oqgraph/ha_oqgraph.cc2
-rw-r--r--storage/xtradb/handler/ha_innodb.cc167
-rw-r--r--storage/xtradb/handler/ha_innodb.h18
-rw-r--r--storage/xtradb/include/row0mysql.h10
-rw-r--r--storage/xtradb/row/row0sel.c115
390 files changed, 99802 insertions, 5284 deletions
diff --git a/.bzrignore b/.bzrignore
index d450bb9594a..f49e2f72922 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1925,6 +1925,10 @@ libmysqld/examples/mysqltest.cc
extra/libevent/event-config.h
libmysqld/opt_table_elimination.cc
libmysqld/ha_federatedx.cc
+libmysqld/multi_range_read.cc
+libmysqld/opt_index_cond_pushdown.cc
+libmysqld/opt_subselect.cc
+libmysqld/sql_join_cache.cc
tmp
libmysqld/debug_sync.cc
client/rpl_filter.cc
@@ -1936,5 +1940,6 @@ sql/client_plugin.c
*.dgcov
libmysqld/create_options.cc
storage/pbxt/bin/xtstat
+libmysqld/sql_expression_cache.cc
mysql-test/mtr_command
scripts/convert-debug-for-diff
diff --git a/configure.in b/configure.in
index 6d2148300de..ed253b9a8e2 100644
--- a/configure.in
+++ b/configure.in
@@ -12,8 +12,12 @@ dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
-
-AC_INIT([MariaDB Server], [5.2.5-MariaDB], [], [mysql])
+dnl
+dnl When merging new MySQL releases, update the version number to match the
+dnl MySQL version number.
+dnl
+dnl Note: the following line must be parseable by win/configure.js:GetVersion()
+AC_INIT([MariaDB Server], [5.3.0-MariaDB-alpha], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
@@ -870,6 +874,7 @@ AC_CHECK_HEADERS([xfs/xfs.h])
#--------------------------------------------------------------------
AC_CHECK_LIB(m, floor, [], AC_CHECK_LIB(m, __infinity))
+AC_CHECK_FUNCS(log2)
AC_CHECK_LIB(nsl_r, gethostbyname_r, [],
AC_CHECK_LIB(nsl, gethostbyname_r))
diff --git a/include/m_string.h b/include/m_string.h
index 26fa41d9cc4..892d3a44868 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -219,7 +219,7 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#endif
#else
#ifdef HAVE_LONG_LONG
- extern char *longlong2str(longlong val,char *dst,int radix, int upcase);
+extern char *longlong2str(longlong val,char *dst,int radix, int upcase);
extern char *longlong10_to_str(longlong val,char *dst,int radix);
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
extern longlong strtoll(const char *str, char **ptr, int base);
diff --git a/include/my_handler.h b/include/my_handler.h
index edb8e21b6a2..275dd92fa18 100644
--- a/include/my_handler.h
+++ b/include/my_handler.h
@@ -123,6 +123,28 @@ extern void my_handler_error_unregister(void);
this amount of bytes.
*/
#define portable_sizeof_char_ptr 8
+
+/**
+ Return values of index_cond_func_xxx functions.
+
+ 0=ICP_NO_MATCH - index tuple doesn't satisfy the pushed index condition (the
+ engine should discard the tuple and go to the next one)
+ 1=ICP_MATCH - index tuple satisfies the pushed index condition (the engine
+ should fetch and return the record)
+ 2=ICP_OUT_OF_RANGE - index tuple is out range that we're scanning, e.g. this
+ 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).
+*/
+
+typedef enum icp_result {
+ ICP_ERROR=-1,
+ ICP_NO_MATCH=0,
+ ICP_MATCH=1,
+ ICP_OUT_OF_RANGE=2
+} ICP_RESULT;
+
+
#ifdef __cplusplus
}
#endif
diff --git a/include/queues.h b/include/queues.h
index d01b73ba999..efe78feb264 100644
--- a/include/queues.h
+++ b/include/queues.h
@@ -1,23 +1,31 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2010 Monty Program Ab
+ All Rights reserved
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
- 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 */
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
/*
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
- Copyright Monty Program KB.
- By monty.
*/
#ifndef _queues_h
@@ -31,38 +39,43 @@ typedef struct st_queue {
void *first_cmp_arg;
uint elements;
uint max_elements;
- uint offset_to_key; /* compare is done on element+offset */
+ uint offset_to_key; /* compare is done on element+offset */
+ uint offset_to_queue_pos; /* If we want to store position in element */
+ uint auto_extent;
int max_at_top; /* Normally 1, set to -1 if queue_top gives max */
int (*compare)(void *, uchar *,uchar *);
- uint auto_extent;
} QUEUE;
+#define queue_first_element(queue) 1
+#define queue_last_element(queue) (queue)->elements
#define queue_top(queue) ((queue)->root[1])
-#define queue_element(queue,index) ((queue)->root[index+1])
+#define queue_element(queue,index) ((queue)->root[index])
#define queue_end(queue) ((queue)->root[(queue)->elements])
-#define queue_replaced(queue) _downheap(queue,1)
+#define queue_replace_top(queue) _downheap(queue, 1, (queue)->root[1])
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
#define queue_set_max_at_top(queue, set_arg) \
(queue)->max_at_top= set_arg ? -1 : 1
+#define queue_remove_top(queue_arg) queue_remove((queue_arg), queue_first_element(queue_arg))
typedef int (*queue_compare)(void *,uchar *, uchar *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
- void *first_cmp_arg);
-int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
- void *first_cmp_arg, uint auto_extent);
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
- void *first_cmp_arg);
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent);
int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,uchar *element);
int queue_insert_safe(QUEUE *queue, uchar *element);
uchar *queue_remove(QUEUE *queue,uint idx);
+void queue_replace(QUEUE *queue,uint idx);
+
#define queue_remove_all(queue) { (queue)->elements= 0; }
#define queue_is_full(queue) (queue->elements == queue->max_elements)
-void _downheap(QUEUE *queue,uint idx);
+void _downheap(QUEUE *queue, uint idx, uchar *element);
void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)
diff --git a/include/thr_alarm.h b/include/thr_alarm.h
index fb906039269..806735b2d38 100644
--- a/include/thr_alarm.h
+++ b/include/thr_alarm.h
@@ -34,7 +34,7 @@ extern "C" {
typedef struct st_alarm_info
{
- ulong next_alarm_time;
+ time_t next_alarm_time;
uint active_alarms;
uint max_used_alarms;
} ALARM_INFO;
@@ -78,15 +78,17 @@ typedef int thr_alarm_entry;
typedef thr_alarm_entry* thr_alarm_t;
typedef struct st_alarm {
- ulong expire_time;
+ time_t expire_time;
thr_alarm_entry alarmed; /* set when alarm is due */
pthread_t thread;
my_thread_id thread_id;
+ uint index_in_queue;
my_bool malloced;
} ALARM;
extern uint thr_client_alarm;
extern pthread_t alarm_thread;
+extern my_bool my_disable_thr_alarm;
#define thr_alarm_init(A) (*(A))=0
#define thr_alarm_in_use(A) (*(A)!= 0)
diff --git a/include/thr_lock.h b/include/thr_lock.h
index 08cc8bd5408..ec24bbabddd 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -123,8 +123,10 @@ typedef struct st_thr_lock_data {
struct st_thr_lock *lock;
pthread_cond_t *cond;
void *status_param; /* Param to status functions */
- void *debug_print_param;
enum thr_lock_type type;
+
+ enum thr_lock_type org_type; /* Cache for MariaDB */
+ void *debug_print_param; /* For error messages */
uint priority;
} THR_LOCK_DATA;
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 27850357127..600a0e90378 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -123,7 +123,8 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/sql_class.cc ../sql/sql_crypt.cc ../sql/sql_cursor.cc
../sql/sql_db.cc ../sql/sql_delete.cc ../sql/sql_derived.cc
../sql/sql_do.cc ../sql/sql_error.cc ../sql/sql_handler.cc
- ../sql/sql_help.cc ../sql/sql_insert.cc ../sql/sql_lex.cc
+ ../sql/sql_help.cc ../sql/sql_insert.cc ../sql/sql_join_cache.cc
+ ../sql/sql_lex.cc
../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc
../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc
../sql/sql_parse.cc ../sql/sql_partition.cc ../sql/sql_plugin.cc
@@ -138,7 +139,11 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
../sql/scheduler.cc ../sql/event_parse_data.cc
- ../sql/create_options.cc
+ ../sql/multi_range_read.cc
+ ../sql/opt_index_cond_pushdown.cc
+ ../sql/opt_subselect.cc
+ ../sql/create_options.cc
+ ../sql/sql_expression_cache.cc
${GEN_SOURCES}
${LIB_SOURCES})
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index ef17a0a6923..682fae81c59 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -58,11 +58,13 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
log_event.cc rpl_record.cc \
log_event_old.cc rpl_record_old.cc \
protocol.cc net_serv.cc opt_range.cc \
+ opt_subselect.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \
sql_load.cc discover.cc sql_locale.cc \
sql_profile.cc \
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
+ sql_join_cache.cc \
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
scheduler.cc sql_connect.cc sql_parse.cc \
sql_prepare.cc sql_derived.cc sql_rename.cc \
@@ -77,7 +79,9 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
debug_sync.cc \
sql_tablespace.cc create_options.cc \
rpl_injector.cc my_user.c partition_info.cc \
- sql_servers.cc event_parse_data.cc opt_table_elimination.cc
+ sql_servers.cc event_parse_data.cc opt_table_elimination.cc \
+ multi_range_read.cc opt_index_cond_pushdown.cc \
+ sql_expression_cache.cc
# automake misses these
sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 07cf5fc8e7b..ce0adc366a6 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -113,7 +113,9 @@ TEST_DIRS = t r include std_data std_data/parts collections \
suite/engines suite/engines/funcs suite/engines/iuds suite/engines/rr_trx \
suite/engines/funcs/r suite/engines/funcs/t suite/engines/iuds/r \
suite/engines/iuds/t suite/engines/rr_trx/include suite/engines/rr_trx/r \
- suite/engines/rr_trx/t
+ suite/engines/rr_trx/t \
+ suite/optimizer_unfixed_bugs/t \
+ suite/optimizer_unfixed_bugs/r
# Used by dist-hook and install-data-local to copy all
# test files into either dist or install directory
diff --git a/mysql-test/include/check_no_concurrent_insert.inc b/mysql-test/include/check_no_concurrent_insert.inc
index 6938c53fd16..f6a3d2052f5 100644
--- a/mysql-test/include/check_no_concurrent_insert.inc
+++ b/mysql-test/include/check_no_concurrent_insert.inc
@@ -43,7 +43,7 @@ connection default;
# of our statement.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert into $table (i) values (0)";
+ where state = "Table lock" and info = "insert into $table (i) values (0)";
--source include/wait_condition.inc
--disable_result_log
diff --git a/mysql-test/include/common-tests.inc b/mysql-test/include/common-tests.inc
index 882ac689498..2273d7d688d 100644
--- a/mysql-test/include/common-tests.inc
+++ b/mysql-test/include/common-tests.inc
@@ -1332,7 +1332,7 @@ explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 a
# Search with a key with LIKE constant
# If the like starts with a certain letter key will be used.
#
-
+--sorted_result
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc
index 566e151dc7f..6b0623bdd5f 100644
--- a/mysql-test/include/index_merge2.inc
+++ b/mysql-test/include/index_merge2.inc
@@ -123,6 +123,7 @@ analyze table t1;
select count(*) from t1;
--replace_column 9 REF
+--replace_result i2,i1 i1,i2
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
@@ -130,6 +131,7 @@ select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
--replace_column 9 REF
+--replace_result i3,i1 i1,i3
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 7ef8adf8e08..5befcce2dd5 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -1179,8 +1179,11 @@ DROP TABLE t1;
create table t1 (a bit(1) not null,b int) engine=myisam;
create table t2 (c int) engine=innodb;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
explain
select b from t1 where a not in (select b from t1,t2 group by a) group by a;
+set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
--echo End of 5.0 tests
diff --git a/mysql-test/include/mrr_tests.inc b/mysql-test/include/mrr_tests.inc
new file mode 100644
index 00000000000..ad7dff61477
--- /dev/null
+++ b/mysql-test/include/mrr_tests.inc
@@ -0,0 +1,118 @@
+
+create table t1(a int);
+show create table t1;
+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 + 10*C.a) from t1 A, t1 B, t1 C;
+
+
+create table t3 (
+ a char(8) not null, b char(8) not null, filler char(200),
+ key(a)
+);
+insert into t3 select @a:=concat('c-', 1000+ A.a, '=w'), @a, 'filler' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 2000+A.a, '=w'),
+ 'filler-1' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 3000+A.a, '=w'),
+ 'filler-2' from t2 A;
+
+# Test empty result set
+select a,filler from t3 where a >= 'c-9011=w';
+
+# Ok, t3.ref_length=6, limit is 64 => 10 elements fit into the buffer
+# Test the cases when buffer gets exhausted at different points in source
+# intervals:
+
+# 1. Split is in the middle of the range
+select a,filler from t3 where a >= 'c-1011=w' and a <= 'c-1015=w';
+
+# 2. Split is at range edge
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+ (a>='c-1014=w' and a <= 'c-1015=w');
+
+# 3. Split is at range edge, with some rows between ranges.
+insert into t3 values ('c-1013=z', 'c-1013=z', 'err');
+insert into t3 values ('a-1014=w', 'a-1014=w', 'err');
+
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+ (a>='c-1014=w' and a <= 'c-1015=w');
+delete from t3 where b in ('c-1013=z', 'a-1014=w');
+
+# 4. Split is within the equality range.
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+ a='c-1014=w' or a='c-1015=w';
+
+# 5. Split is at the edge of equality range.
+insert into t3 values ('c-1013=w', 'del-me', 'inserted');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+ a='c-1014=w' or a='c-1015=w';
+delete from t3 where b='del-me';
+
+# PK tests are not included here.
+
+alter table t3 add primary key(b);
+
+## PK scan tests
+# 6. Split is between 'unique' PK ranges
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+ b IN ('c-1019=w', 'c-1020=w', 'c-1021=w',
+ 'c-1022=w', 'c-1023=w', 'c-1024=w');
+
+# 7. Between non-uniq and uniq range
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1020=w') or
+ b IN ('c-1021=w', 'c-1022=w', 'c-1023=w');
+
+# 8. Between uniq and non-uniq range
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+ b IN ('c-1019=w', 'c-1020=w') or
+ (b>='c-1021=w' and b<= 'c-1023=w');
+## End of PK scan tests
+
+#
+# Now try different keypart types and special values
+#
+--disable_warnings
+drop table if exists t4;
+--enable_warnings
+create table t4 (a varchar(10), b int, c char(10), filler char(200),
+ key idx1 (a, b, c));
+
+# insert buffer_size * 1.5 all-NULL tuples
+insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
+
+insert into t4 (a,b,c,filler)
+ select 'b-1',NULL,'c-1', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+ select 'b-1',NULL,'c-222', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+ select 'bb-1',NULL,'cc-2', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+ select 'zz-1',NULL,'cc-2', 'filler-data' from t2 order by a limit 500;
+
+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');
+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');
+
+explain
+ select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
+select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
+
+select * from t4 ignore index(idx1) where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
+drop table t1, t2, t3, t4;
+
+#
+# Check how ICP works with NULLs and partially-covered indexes
+#
+create table t1 (a int, b int not null,unique key (a,b),index(b));
+insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6);
+create table t2 like t1;
+insert into t2 select * from t1;
+alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
+
+select * from t1 where a is null;
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
+
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
+drop table t1, t2;
diff --git a/mysql-test/include/world.inc b/mysql-test/include/world.inc
new file mode 100644
index 00000000000..eae6556c422
--- /dev/null
+++ b/mysql-test/include/world.inc
@@ -0,0 +1,5343 @@
+#
+# Populate the world database
+#
+
+# Table Country
+
+INSERT INTO Country VALUES
+('AFG','Afghanistan',652090.00,22720000,1),
+('NLD','Netherlands',41526.00,15864000,5),
+('ANT','Netherlands Antilles',800.00,217000,33),
+('ALB','Albania',28748.00,3401200,34),
+('DZA','Algeria',2381741.00,31471000,35),
+('ASM','American Samoa',199.00,68000,54),
+('AND','Andorra',468.00,78000,55),
+('AGO','Angola',1246700.00,12878000,56),
+('AIA','Anguilla',96.00,8000,62),
+('ATG','Antigua and Barbuda',442.00,68000,63),
+('ARE','United Arab Emirates',83600.00,2441000,65),
+('ARG','Argentina',2780400.00,37032000,69),
+('ARM','Armenia',29800.00,3520000,126),
+('ABW','Aruba',193.00,103000,129),
+('AUS','Australia',7741220.00,18886000,135),
+('AZE','Azerbaijan',86600.00,7734000,144),
+('BHS','Bahamas',13878.00,307000,148),
+('BHR','Bahrain',694.00,617000,149),
+('BGD','Bangladesh',143998.00,129155000,150),
+('BRB','Barbados',430.00,270000,174),
+('BEL','Belgium',30518.00,10239000,179),
+('BLZ','Belize',22696.00,241000,185),
+('BEN','Benin',112622.00,6097000,187),
+('BMU','Bermuda',53.00,65000,191),
+('BTN','Bhutan',47000.00,2124000,192),
+('BOL','Bolivia',1098581.00,8329000,194),
+('BIH','Bosnia and Herzegovina',51197.00,3972000,201),
+('BWA','Botswana',581730.00,1622000,204),
+('BRA','Brazil',8547403.00,170115000,211),
+('GBR','United Kingdom',242900.00,59623400,456),
+('VGB','Virgin Islands, British',151.00,21000,537),
+('BRN','Brunei',5765.00,328000,538),
+('BGR','Bulgaria',110994.00,8190900,539),
+('BFA','Burkina Faso',274000.00,11937000,549),
+('BDI','Burundi',27834.00,6695000,552),
+('CYM','Cayman Islands',264.00,38000,553),
+('CHL','Chile',756626.00,15211000,554),
+('COK','Cook Islands',236.00,20000,583),
+('CRI','Costa Rica',51100.00,4023000,584),
+('DJI','Djibouti',23200.00,638000,585),
+('DMA','Dominica',751.00,71000,586),
+('DOM','Dominican Republic',48511.00,8495000,587),
+('ECU','Ecuador',283561.00,12646000,594),
+('EGY','Egypt',1001449.00,68470000,608),
+('SLV','El Salvador',21041.00,6276000,645),
+('ERI','Eritrea',117600.00,3850000,652),
+('ESP','Spain',505992.00,39441700,653),
+('ZAF','South Africa',1221037.00,40377000,716),
+('ETH','Ethiopia',1104300.00,62565000,756),
+('FLK','Falkland Islands',12173.00,2000,763),
+('FJI','Fiji Islands',18274.00,817000,764),
+('PHL','Philippines',300000.00,75967000,766),
+('FRO','Faroe Islands',1399.00,43000,901),
+('GAB','Gabon',267668.00,1226000,902),
+('GMB','Gambia',11295.00,1305000,904),
+('GEO','Georgia',69700.00,4968000,905),
+('GHA','Ghana',238533.00,20212000,910),
+('GIB','Gibraltar',6.00,25000,915),
+('GRD','Grenada',344.00,94000,916),
+('GRL','Greenland',2166090.00,56000,917),
+('GLP','Guadeloupe',1705.00,456000,919),
+('GUM','Guam',549.00,168000,921),
+('GTM','Guatemala',108889.00,11385000,922),
+('GIN','Guinea',245857.00,7430000,926),
+('GNB','Guinea-Bissau',36125.00,1213000,927),
+('GUY','Guyana',214969.00,861000,928),
+('HTI','Haiti',27750.00,8222000,929),
+('HND','Honduras',112088.00,6485000,933),
+('HKG','Hong Kong',1075.00,6782000,937),
+('SJM','Svalbard and Jan Mayen',62422.00,3200,938),
+('IDN','Indonesia',1904569.00,212107000,939),
+('IND','India',3287263.00,1013662000,1109),
+('IRQ','Iraq',438317.00,23115000,1365),
+('IRN','Iran',1648195.00,67702000,1380),
+('IRL','Ireland',70273.00,3775100,1447),
+('ISL','Iceland',103000.00,279000,1449),
+('ISR','Israel',21056.00,6217000,1450),
+('ITA','Italy',301316.00,57680000,1464),
+('TMP','East Timor',14874.00,885000,1522),
+('AUT','Austria',83859.00,8091800,1523),
+('JAM','Jamaica',10990.00,2583000,1530),
+('JPN','Japan',377829.00,126714000,1532),
+('YEM','Yemen',527968.00,18112000,1780),
+('JOR','Jordan',88946.00,5083000,1786),
+('CXR','Christmas Island',135.00,2500,1791),
+('YUG','Yugoslavia',102173.00,10640000,1792),
+('KHM','Cambodia',181035.00,11168000,1800),
+('CMR','Cameroon',475442.00,15085000,1804),
+('CAN','Canada',9970610.00,31147000,1822),
+('CPV','Cape Verde',4033.00,428000,1859),
+('KAZ','Kazakstan',2724900.00,16223000,1864),
+('KEN','Kenya',580367.00,30080000,1881),
+('CAF','Central African Republic',622984.00,3615000,1889),
+('CHN','China',9572900.00,1277558000,1891),
+('KGZ','Kyrgyzstan',199900.00,4699000,2253),
+('KIR','Kiribati',726.00,83000,2256),
+('COL','Colombia',1138914.00,42321000,2257),
+('COM','Comoros',1862.00,578000,2295),
+('COG','Congo',342000.00,2943000,2296),
+('COD','Congo, The Democratic Republic of the',2344858.00,51654000,2298),
+('CCK','Cocos (Keeling) Islands',14.00,600,2317),
+('PRK','North Korea',120538.00,24039000,2318),
+('KOR','South Korea',99434.00,46844000,2331),
+('GRC','Greece',131626.00,10545700,2401),
+('HRV','Croatia',56538.00,4473000,2409),
+('CUB','Cuba',110861.00,11201000,2413),
+('KWT','Kuwait',17818.00,1972000,2429),
+('CYP','Cyprus',9251.00,754700,2430),
+('LAO','Laos',236800.00,5433000,2432),
+('LVA','Latvia',64589.00,2424200,2434),
+('LSO','Lesotho',30355.00,2153000,2437),
+('LBN','Lebanon',10400.00,3282000,2438),
+('LBR','Liberia',111369.00,3154000,2440),
+('LBY','Libyan Arab Jamahiriya',1759540.00,5605000,2441),
+('LIE','Liechtenstein',160.00,32300,2446),
+('LTU','Lithuania',65301.00,3698500,2447),
+('LUX','Luxembourg',2586.00,435700,2452),
+('ESH','Western Sahara',266000.00,293000,2453),
+('MAC','Macao',18.00,473000,2454),
+('MDG','Madagascar',587041.00,15942000,2455),
+('MKD','Macedonia',25713.00,2024000,2460),
+('MWI','Malawi',118484.00,10925000,2462),
+('MDV','Maldives',298.00,286000,2463),
+('MYS','Malaysia',329758.00,22244000,2464),
+('MLI','Mali',1240192.00,11234000,2482),
+('MLT','Malta',316.00,380200,2484),
+('MAR','Morocco',446550.00,28351000,2486),
+('MHL','Marshall Islands',181.00,64000,2507),
+('MTQ','Martinique',1102.00,395000,2508),
+('MRT','Mauritania',1025520.00,2670000,2509),
+('MUS','Mauritius',2040.00,1158000,2511),
+('MYT','Mayotte',373.00,149000,2514),
+('MEX','Mexico',1958201.00,98881000,2515),
+('FSM','Micronesia, Federated States of',702.00,119000,2689),
+('MDA','Moldova',33851.00,4380000,2690),
+('MCO','Monaco',1.50,34000,2695),
+('MNG','Mongolia',1566500.00,2662000,2696),
+('MSR','Montserrat',102.00,11000,2697),
+('MOZ','Mozambique',801590.00,19680000,2698),
+('MMR','Myanmar',676578.00,45611000,2710),
+('NAM','Namibia',824292.00,1726000,2726),
+('NRU','Nauru',21.00,12000,2728),
+('NPL','Nepal',147181.00,23930000,2729),
+('NIC','Nicaragua',130000.00,5074000,2734),
+('NER','Niger',1267000.00,10730000,2738),
+('NGA','Nigeria',923768.00,111506000,2754),
+('NIU','Niue',260.00,2000,2805),
+('NFK','Norfolk Island',36.00,2000,2806),
+('NOR','Norway',323877.00,4478500,2807),
+('CIV','Côte d’Ivoire',322463.00,14786000,2814),
+('OMN','Oman',309500.00,2542000,2821),
+('PAK','Pakistan',796095.00,156483000,2831),
+('PLW','Palau',459.00,19000,2881),
+('PAN','Panama',75517.00,2856000,2882),
+('PNG','Papua New Guinea',462840.00,4807000,2884),
+('PRY','Paraguay',406752.00,5496000,2885),
+('PER','Peru',1285216.00,25662000,2890),
+('PCN','Pitcairn',49.00,50,2912),
+('MNP','Northern Mariana Islands',464.00,78000,2913),
+('PRT','Portugal',91982.00,9997600,2914),
+('PRI','Puerto Rico',8875.00,3869000,2919),
+('POL','Poland',323250.00,38653600,2928),
+('GNQ','Equatorial Guinea',28051.00,453000,2972),
+('QAT','Qatar',11000.00,599000,2973),
+('FRA','France',551500.00,59225700,2974),
+('GUF','French Guiana',90000.00,181000,3014),
+('PYF','French Polynesia',4000.00,235000,3016),
+('REU','Réunion',2510.00,699000,3017),
+('ROM','Romania',238391.00,22455500,3018),
+('RWA','Rwanda',26338.00,7733000,3047),
+('SWE','Sweden',449964.00,8861400,3048),
+('SHN','Saint Helena',314.00,6000,3063),
+('KNA','Saint Kitts and Nevis',261.00,38000,3064),
+('LCA','Saint Lucia',622.00,154000,3065),
+('VCT','Saint Vincent and the Grenadines',388.00,114000,3066),
+('SPM','Saint Pierre and Miquelon',242.00,7000,3067),
+('DEU','Germany',357022.00,82164700,3068),
+('SLB','Solomon Islands',28896.00,444000,3161),
+('ZMB','Zambia',752618.00,9169000,3162),
+('WSM','Samoa',2831.00,180000,3169),
+('SMR','San Marino',61.00,27000,3171),
+('STP','Sao Tome and Principe',964.00,147000,3172),
+('SAU','Saudi Arabia',2149690.00,21607000,3173),
+('SEN','Senegal',196722.00,9481000,3198),
+('SYC','Seychelles',455.00,77000,3206),
+('SLE','Sierra Leone',71740.00,4854000,3207),
+('SGP','Singapore',618.00,3567000,3208),
+('SVK','Slovakia',49012.00,5398700,3209),
+('SVN','Slovenia',20256.00,1987800,3212),
+('SOM','Somalia',637657.00,10097000,3214),
+('LKA','Sri Lanka',65610.00,18827000,3217),
+('SDN','Sudan',2505813.00,29490000,3225),
+('FIN','Finland',338145.00,5171300,3236),
+('SUR','Suriname',163265.00,417000,3243),
+('SWZ','Swaziland',17364.00,1008000,3244),
+('CHE','Switzerland',41284.00,7160400,3248),
+('SYR','Syria',185180.00,16125000,3250),
+('TJK','Tajikistan',143100.00,6188000,3261),
+('TWN','Taiwan',36188.00,22256000,3263),
+('TZA','Tanzania',883749.00,33517000,3306),
+('DNK','Denmark',43094.00,5330000,3315),
+('THA','Thailand',513115.00,61399000,3320),
+('TGO','Togo',56785.00,4629000,3332),
+('TKL','Tokelau',12.00,2000,3333),
+('TON','Tonga',650.00,99000,3334),
+('TTO','Trinidad and Tobago',5130.00,1295000,3336),
+('TCD','Chad',1284000.00,7651000,3337),
+('CZE','Czech Republic',78866.00,10278100,3339),
+('TUN','Tunisia',163610.00,9586000,3349),
+('TUR','Turkey',774815.00,66591000,3358),
+('TKM','Turkmenistan',488100.00,4459000,3419),
+('TCA','Turks and Caicos Islands',430.00,17000,3423),
+('TUV','Tuvalu',26.00,12000,3424),
+('UGA','Uganda',241038.00,21778000,3425),
+('UKR','Ukraine',603700.00,50456000,3426),
+('HUN','Hungary',93030.00,10043200,3483),
+('URY','Uruguay',175016.00,3337000,3492),
+('NCL','New Caledonia',18575.00,214000,3493),
+('NZL','New Zealand',270534.00,3862000,3499),
+('UZB','Uzbekistan',447400.00,24318000,3503),
+('BLR','Belarus',207600.00,10236000,3520),
+('WLF','Wallis and Futuna',200.00,15000,3536),
+('VUT','Vanuatu',12189.00,190000,3537),
+('VAT','Holy See (Vatican City State)',0.40,1000,3538),
+('VEN','Venezuela',912050.00,24170000,3539),
+('RUS','Russian Federation',17075400.00,146934000,3580),
+('VNM','Vietnam',331689.00,79832000,3770),
+('EST','Estonia',45227.00,1439200,3791),
+('USA','United States',9363520.00,278357000,3813),
+('VIR','Virgin Islands, U.S.',347.00,93000,4067),
+('ZWE','Zimbabwe',390757.00,11669000,4068),
+('PSE','Palestine',6257.00,3101000,4074),
+('ATA','Antarctica',13120000.00,0,NULL),
+('BVT','Bouvet Island',59.00,0,NULL),
+('IOT','British Indian Ocean Territory',78.00,0,NULL),
+('SGS','South Georgia and the South Sandwich Islands',3903.00,0,NULL),
+('HMD','Heard Island and McDonald Islands',359.00,0,NULL),
+('ATF','French Southern territories',7780.00,0,NULL),
+('UMI','United States Minor Outlying Islands',16.00,0,NULL);
+
+# Table City
+
+INSERT INTO City VALUES
+(1,'Kabul','AFG',1780000),
+(2,'Qandahar','AFG',237500),
+(3,'Herat','AFG',186800),
+(4,'Mazar-e-Sharif','AFG',127800),
+(5,'Amsterdam','NLD',731200),
+(6,'Rotterdam','NLD',593321),
+(7,'Haag','NLD',440900),
+(8,'Utrecht','NLD',234323),
+(9,'Eindhoven','NLD',201843),
+(10,'Tilburg','NLD',193238),
+(11,'Groningen','NLD',172701),
+(12,'Breda','NLD',160398),
+(13,'Apeldoorn','NLD',153491),
+(14,'Nijmegen','NLD',152463),
+(15,'Enschede','NLD',149544),
+(16,'Haarlem','NLD',148772),
+(17,'Almere','NLD',142465),
+(18,'Arnhem','NLD',138020),
+(19,'Zaanstad','NLD',135621),
+(20,'´s-Hertogenbosch','NLD',129170),
+(21,'Amersfoort','NLD',126270),
+(22,'Maastricht','NLD',122087),
+(23,'Dordrecht','NLD',119811),
+(24,'Leiden','NLD',117196),
+(25,'Haarlemmermeer','NLD',110722),
+(26,'Zoetermeer','NLD',110214),
+(27,'Emmen','NLD',105853),
+(28,'Zwolle','NLD',105819),
+(29,'Ede','NLD',101574),
+(30,'Delft','NLD',95268),
+(31,'Heerlen','NLD',95052),
+(32,'Alkmaar','NLD',92713),
+(33,'Willemstad','ANT',2345),
+(34,'Tirana','ALB',270000),
+(35,'Alger','DZA',2168000),
+(36,'Oran','DZA',609823),
+(37,'Constantine','DZA',443727),
+(38,'Annaba','DZA',222518),
+(39,'Batna','DZA',183377),
+(40,'Sétif','DZA',179055),
+(41,'Sidi Bel Abbès','DZA',153106),
+(42,'Skikda','DZA',128747),
+(43,'Biskra','DZA',128281),
+(44,'Blida (el-Boulaida)','DZA',127284),
+(45,'Béjaïa','DZA',117162),
+(46,'Mostaganem','DZA',115212),
+(47,'Tébessa','DZA',112007),
+(48,'Tlemcen (Tilimsen)','DZA',110242),
+(49,'Béchar','DZA',107311),
+(50,'Tiaret','DZA',100118),
+(51,'Ech-Chleff (el-Asnam)','DZA',96794),
+(52,'Ghardaïa','DZA',89415),
+(53,'Tafuna','ASM',5200),
+(54,'Fagatogo','ASM',2323),
+(55,'Andorra la Vella','AND',21189),
+(56,'Luanda','AGO',2022000),
+(57,'Huambo','AGO',163100),
+(58,'Lobito','AGO',130000),
+(59,'Benguela','AGO',128300),
+(60,'Namibe','AGO',118200),
+(61,'South Hill','AIA',961),
+(62,'The Valley','AIA',595),
+(63,'Saint John´s','ATG',24000),
+(64,'Dubai','ARE',669181),
+(65,'Abu Dhabi','ARE',398695),
+(66,'Sharja','ARE',320095),
+(67,'al-Ayn','ARE',225970),
+(68,'Ajman','ARE',114395),
+(69,'Buenos Aires','ARG',2982146),
+(70,'La Matanza','ARG',1266461),
+(71,'Córdoba','ARG',1157507),
+(72,'Rosario','ARG',907718),
+(73,'Lomas de Zamora','ARG',622013),
+(74,'Quilmes','ARG',559249),
+(75,'Almirante Brown','ARG',538918),
+(76,'La Plata','ARG',521936),
+(77,'Mar del Plata','ARG',512880),
+(78,'San Miguel de Tucumán','ARG',470809),
+(79,'Lanús','ARG',469735),
+(80,'Merlo','ARG',463846),
+(81,'General San Martín','ARG',422542),
+(82,'Salta','ARG',367550),
+(83,'Moreno','ARG',356993),
+(84,'Santa Fé','ARG',353063),
+(85,'Avellaneda','ARG',353046),
+(86,'Tres de Febrero','ARG',352311),
+(87,'Morón','ARG',349246),
+(88,'Florencio Varela','ARG',315432),
+(89,'San Isidro','ARG',306341),
+(90,'Tigre','ARG',296226),
+(91,'Malvinas Argentinas','ARG',290335),
+(92,'Vicente López','ARG',288341),
+(93,'Berazategui','ARG',276916),
+(94,'Corrientes','ARG',258103),
+(95,'San Miguel','ARG',248700),
+(96,'Bahía Blanca','ARG',239810),
+(97,'Esteban Echeverría','ARG',235760),
+(98,'Resistencia','ARG',229212),
+(99,'José C. Paz','ARG',221754),
+(100,'Paraná','ARG',207041),
+(101,'Godoy Cruz','ARG',206998),
+(102,'Posadas','ARG',201273),
+(103,'Guaymallén','ARG',200595),
+(104,'Santiago del Estero','ARG',189947),
+(105,'San Salvador de Jujuy','ARG',178748),
+(106,'Hurlingham','ARG',170028),
+(107,'Neuquén','ARG',167296),
+(108,'Ituzaingó','ARG',158197),
+(109,'San Fernando','ARG',153036),
+(110,'Formosa','ARG',147636),
+(111,'Las Heras','ARG',145823),
+(112,'La Rioja','ARG',138117),
+(113,'San Fernando del Valle de Cata','ARG',134935),
+(114,'Río Cuarto','ARG',134355),
+(115,'Comodoro Rivadavia','ARG',124104),
+(116,'Mendoza','ARG',123027),
+(117,'San Nicolás de los Arroyos','ARG',119302),
+(118,'San Juan','ARG',119152),
+(119,'Escobar','ARG',116675),
+(120,'Concordia','ARG',116485),
+(121,'Pilar','ARG',113428),
+(122,'San Luis','ARG',110136),
+(123,'Ezeiza','ARG',99578),
+(124,'San Rafael','ARG',94651),
+(125,'Tandil','ARG',91101),
+(126,'Yerevan','ARM',1248700),
+(127,'Gjumri','ARM',211700),
+(128,'Vanadzor','ARM',172700),
+(129,'Oranjestad','ABW',29034),
+(130,'Sydney','AUS',3276207),
+(131,'Melbourne','AUS',2865329),
+(132,'Brisbane','AUS',1291117),
+(133,'Perth','AUS',1096829),
+(134,'Adelaide','AUS',978100),
+(135,'Canberra','AUS',322723),
+(136,'Gold Coast','AUS',311932),
+(137,'Newcastle','AUS',270324),
+(138,'Central Coast','AUS',227657),
+(139,'Wollongong','AUS',219761),
+(140,'Hobart','AUS',126118),
+(141,'Geelong','AUS',125382),
+(142,'Townsville','AUS',109914),
+(143,'Cairns','AUS',92273),
+(144,'Baku','AZE',1787800),
+(145,'Gäncä','AZE',299300),
+(146,'Sumqayit','AZE',283000),
+(147,'Mingäçevir','AZE',93900),
+(148,'Nassau','BHS',172000),
+(149,'al-Manama','BHR',148000),
+(150,'Dhaka','BGD',3612850),
+(151,'Chittagong','BGD',1392860),
+(152,'Khulna','BGD',663340),
+(153,'Rajshahi','BGD',294056),
+(154,'Narayanganj','BGD',202134),
+(155,'Rangpur','BGD',191398),
+(156,'Mymensingh','BGD',188713),
+(157,'Barisal','BGD',170232),
+(158,'Tungi','BGD',168702),
+(159,'Jessore','BGD',139710),
+(160,'Comilla','BGD',135313),
+(161,'Nawabganj','BGD',130577),
+(162,'Dinajpur','BGD',127815),
+(163,'Bogra','BGD',120170),
+(164,'Sylhet','BGD',117396),
+(165,'Brahmanbaria','BGD',109032),
+(166,'Tangail','BGD',106004),
+(167,'Jamalpur','BGD',103556),
+(168,'Pabna','BGD',103277),
+(169,'Naogaon','BGD',101266),
+(170,'Sirajganj','BGD',99669),
+(171,'Narsinghdi','BGD',98342),
+(172,'Saidpur','BGD',96777),
+(173,'Gazipur','BGD',96717),
+(174,'Bridgetown','BRB',6070),
+(175,'Antwerpen','BEL',446525),
+(176,'Gent','BEL',224180),
+(177,'Charleroi','BEL',200827),
+(178,'Liège','BEL',185639),
+(179,'Bruxelles [Brussel]','BEL',133859),
+(180,'Brugge','BEL',116246),
+(181,'Schaerbeek','BEL',105692),
+(182,'Namur','BEL',105419),
+(183,'Mons','BEL',90935),
+(184,'Belize City','BLZ',55810),
+(185,'Belmopan','BLZ',7105),
+(186,'Cotonou','BEN',536827),
+(187,'Porto-Novo','BEN',194000),
+(188,'Djougou','BEN',134099),
+(189,'Parakou','BEN',103577),
+(190,'Saint George','BMU',1800),
+(191,'Hamilton','BMU',1200),
+(192,'Thimphu','BTN',22000),
+(193,'Santa Cruz de la Sierra','BOL',935361),
+(194,'La Paz','BOL',758141),
+(195,'El Alto','BOL',534466),
+(196,'Cochabamba','BOL',482800),
+(197,'Oruro','BOL',223553),
+(198,'Sucre','BOL',178426),
+(199,'Potosí','BOL',140642),
+(200,'Tarija','BOL',125255);
+INSERT INTO City VALUES
+(201,'Sarajevo','BIH',360000),
+(202,'Banja Luka','BIH',143079),
+(203,'Zenica','BIH',96027),
+(204,'Gaborone','BWA',213017),
+(205,'Francistown','BWA',101805),
+(206,'São Paulo','BRA',9968485),
+(207,'Rio de Janeiro','BRA',5598953),
+(208,'Salvador','BRA',2302832),
+(209,'Belo Horizonte','BRA',2139125),
+(210,'Fortaleza','BRA',2097757),
+(211,'Brasília','BRA',1969868),
+(212,'Curitiba','BRA',1584232),
+(213,'Recife','BRA',1378087),
+(214,'Porto Alegre','BRA',1314032),
+(215,'Manaus','BRA',1255049),
+(216,'Belém','BRA',1186926),
+(217,'Guarulhos','BRA',1095874),
+(218,'Goiânia','BRA',1056330),
+(219,'Campinas','BRA',950043),
+(220,'São Gonçalo','BRA',869254),
+(221,'Nova Iguaçu','BRA',862225),
+(222,'São Luís','BRA',837588),
+(223,'Maceió','BRA',786288),
+(224,'Duque de Caxias','BRA',746758),
+(225,'São Bernardo do Campo','BRA',723132),
+(226,'Teresina','BRA',691942),
+(227,'Natal','BRA',688955),
+(228,'Osasco','BRA',659604),
+(229,'Campo Grande','BRA',649593),
+(230,'Santo André','BRA',630073),
+(231,'João Pessoa','BRA',584029),
+(232,'Jaboatão dos Guararapes','BRA',558680),
+(233,'Contagem','BRA',520801),
+(234,'São José dos Campos','BRA',515553),
+(235,'Uberlândia','BRA',487222),
+(236,'Feira de Santana','BRA',479992),
+(237,'Ribeirão Preto','BRA',473276),
+(238,'Sorocaba','BRA',466823),
+(239,'Niterói','BRA',459884),
+(240,'Cuiabá','BRA',453813),
+(241,'Juiz de Fora','BRA',450288),
+(242,'Aracaju','BRA',445555),
+(243,'São João de Meriti','BRA',440052),
+(244,'Londrina','BRA',432257),
+(245,'Joinville','BRA',428011),
+(246,'Belford Roxo','BRA',425194),
+(247,'Santos','BRA',408748),
+(248,'Ananindeua','BRA',400940),
+(249,'Campos dos Goytacazes','BRA',398418),
+(250,'Mauá','BRA',375055),
+(251,'Carapicuíba','BRA',357552),
+(252,'Olinda','BRA',354732),
+(253,'Campina Grande','BRA',352497),
+(254,'São José do Rio Preto','BRA',351944),
+(255,'Caxias do Sul','BRA',349581),
+(256,'Moji das Cruzes','BRA',339194),
+(257,'Diadema','BRA',335078),
+(258,'Aparecida de Goiânia','BRA',324662),
+(259,'Piracicaba','BRA',319104),
+(260,'Cariacica','BRA',319033),
+(261,'Vila Velha','BRA',318758),
+(262,'Pelotas','BRA',315415),
+(263,'Bauru','BRA',313670),
+(264,'Porto Velho','BRA',309750),
+(265,'Serra','BRA',302666),
+(266,'Betim','BRA',302108),
+(267,'Jundíaí','BRA',296127),
+(268,'Canoas','BRA',294125),
+(269,'Franca','BRA',290139),
+(270,'São Vicente','BRA',286848),
+(271,'Maringá','BRA',286461),
+(272,'Montes Claros','BRA',286058),
+(273,'Anápolis','BRA',282197),
+(274,'Florianópolis','BRA',281928),
+(275,'Petrópolis','BRA',279183),
+(276,'Itaquaquecetuba','BRA',270874),
+(277,'Vitória','BRA',270626),
+(278,'Ponta Grossa','BRA',268013),
+(279,'Rio Branco','BRA',259537),
+(280,'Foz do Iguaçu','BRA',259425),
+(281,'Macapá','BRA',256033),
+(282,'Ilhéus','BRA',254970),
+(283,'Vitória da Conquista','BRA',253587),
+(284,'Uberaba','BRA',249225),
+(285,'Paulista','BRA',248473),
+(286,'Limeira','BRA',245497),
+(287,'Blumenau','BRA',244379),
+(288,'Caruaru','BRA',244247),
+(289,'Santarém','BRA',241771),
+(290,'Volta Redonda','BRA',240315),
+(291,'Novo Hamburgo','BRA',239940),
+(292,'Caucaia','BRA',238738),
+(293,'Santa Maria','BRA',238473),
+(294,'Cascavel','BRA',237510),
+(295,'Guarujá','BRA',237206),
+(296,'Ribeirão das Neves','BRA',232685),
+(297,'Governador Valadares','BRA',231724),
+(298,'Taubaté','BRA',229130),
+(299,'Imperatriz','BRA',224564),
+(300,'Gravataí','BRA',223011),
+(301,'Embu','BRA',222223),
+(302,'Mossoró','BRA',214901),
+(303,'Várzea Grande','BRA',214435),
+(304,'Petrolina','BRA',210540),
+(305,'Barueri','BRA',208426),
+(306,'Viamão','BRA',207557),
+(307,'Ipatinga','BRA',206338),
+(308,'Juazeiro','BRA',201073),
+(309,'Juazeiro do Norte','BRA',199636),
+(310,'Taboão da Serra','BRA',197550),
+(311,'São José dos Pinhais','BRA',196884),
+(312,'Magé','BRA',196147),
+(313,'Suzano','BRA',195434),
+(314,'São Leopoldo','BRA',189258),
+(315,'Marília','BRA',188691),
+(316,'São Carlos','BRA',187122),
+(317,'Sumaré','BRA',186205),
+(318,'Presidente Prudente','BRA',185340),
+(319,'Divinópolis','BRA',185047),
+(320,'Sete Lagoas','BRA',182984),
+(321,'Rio Grande','BRA',182222),
+(322,'Itabuna','BRA',182148),
+(323,'Jequié','BRA',179128),
+(324,'Arapiraca','BRA',178988),
+(325,'Colombo','BRA',177764),
+(326,'Americana','BRA',177409),
+(327,'Alvorada','BRA',175574),
+(328,'Araraquara','BRA',174381),
+(329,'Itaboraí','BRA',173977),
+(330,'Santa Bárbara d´Oeste','BRA',171657),
+(331,'Nova Friburgo','BRA',170697),
+(332,'Jacareí','BRA',170356),
+(333,'Araçatuba','BRA',169303),
+(334,'Barra Mansa','BRA',168953),
+(335,'Praia Grande','BRA',168434),
+(336,'Marabá','BRA',167795),
+(337,'Criciúma','BRA',167661),
+(338,'Boa Vista','BRA',167185),
+(339,'Passo Fundo','BRA',166343),
+(340,'Dourados','BRA',164716),
+(341,'Santa Luzia','BRA',164704),
+(342,'Rio Claro','BRA',163551),
+(343,'Maracanaú','BRA',162022),
+(344,'Guarapuava','BRA',160510),
+(345,'Rondonópolis','BRA',155115),
+(346,'São José','BRA',155105),
+(347,'Cachoeiro de Itapemirim','BRA',155024),
+(348,'Nilópolis','BRA',153383),
+(349,'Itapevi','BRA',150664),
+(350,'Cabo de Santo Agostinho','BRA',149964),
+(351,'Camaçari','BRA',149146),
+(352,'Sobral','BRA',146005),
+(353,'Itajaí','BRA',145197),
+(354,'Chapecó','BRA',144158),
+(355,'Cotia','BRA',140042),
+(356,'Lages','BRA',139570),
+(357,'Ferraz de Vasconcelos','BRA',139283),
+(358,'Indaiatuba','BRA',135968),
+(359,'Hortolândia','BRA',135755),
+(360,'Caxias','BRA',133980),
+(361,'São Caetano do Sul','BRA',133321),
+(362,'Itu','BRA',132736),
+(363,'Nossa Senhora do Socorro','BRA',131351),
+(364,'Parnaíba','BRA',129756),
+(365,'Poços de Caldas','BRA',129683),
+(366,'Teresópolis','BRA',128079),
+(367,'Barreiras','BRA',127801),
+(368,'Castanhal','BRA',127634),
+(369,'Alagoinhas','BRA',126820),
+(370,'Itapecerica da Serra','BRA',126672),
+(371,'Uruguaiana','BRA',126305),
+(372,'Paranaguá','BRA',126076),
+(373,'Ibirité','BRA',125982),
+(374,'Timon','BRA',125812),
+(375,'Luziânia','BRA',125597),
+(376,'Macaé','BRA',125597),
+(377,'Teófilo Otoni','BRA',124489),
+(378,'Moji-Guaçu','BRA',123782),
+(379,'Palmas','BRA',121919),
+(380,'Pindamonhangaba','BRA',121904),
+(381,'Francisco Morato','BRA',121197),
+(382,'Bagé','BRA',120793),
+(383,'Sapucaia do Sul','BRA',120217),
+(384,'Cabo Frio','BRA',119503),
+(385,'Itapetininga','BRA',119391),
+(386,'Patos de Minas','BRA',119262),
+(387,'Camaragibe','BRA',118968),
+(388,'Bragança Paulista','BRA',116929),
+(389,'Queimados','BRA',115020),
+(390,'Araguaína','BRA',114948),
+(391,'Garanhuns','BRA',114603),
+(392,'Vitória de Santo Antão','BRA',113595),
+(393,'Santa Rita','BRA',113135),
+(394,'Barbacena','BRA',113079),
+(395,'Abaetetuba','BRA',111258),
+(396,'Jaú','BRA',109965),
+(397,'Lauro de Freitas','BRA',109236),
+(398,'Franco da Rocha','BRA',108964),
+(399,'Teixeira de Freitas','BRA',108441),
+(400,'Varginha','BRA',108314);
+INSERT INTO City VALUES
+(401,'Ribeirão Pires','BRA',108121),
+(402,'Sabará','BRA',107781),
+(403,'Catanduva','BRA',107761),
+(404,'Rio Verde','BRA',107755),
+(405,'Botucatu','BRA',107663),
+(406,'Colatina','BRA',107354),
+(407,'Santa Cruz do Sul','BRA',106734),
+(408,'Linhares','BRA',106278),
+(409,'Apucarana','BRA',105114),
+(410,'Barretos','BRA',104156),
+(411,'Guaratinguetá','BRA',103433),
+(412,'Cachoeirinha','BRA',103240),
+(413,'Codó','BRA',103153),
+(414,'Jaraguá do Sul','BRA',102580),
+(415,'Cubatão','BRA',102372),
+(416,'Itabira','BRA',102217),
+(417,'Itaituba','BRA',101320),
+(418,'Araras','BRA',101046),
+(419,'Resende','BRA',100627),
+(420,'Atibaia','BRA',100356),
+(421,'Pouso Alegre','BRA',100028),
+(422,'Toledo','BRA',99387),
+(423,'Crato','BRA',98965),
+(424,'Passos','BRA',98570),
+(425,'Araguari','BRA',98399),
+(426,'São José de Ribamar','BRA',98318),
+(427,'Pinhais','BRA',98198),
+(428,'Sertãozinho','BRA',98140),
+(429,'Conselheiro Lafaiete','BRA',97507),
+(430,'Paulo Afonso','BRA',97291),
+(431,'Angra dos Reis','BRA',96864),
+(432,'Eunápolis','BRA',96610),
+(433,'Salto','BRA',96348),
+(434,'Ourinhos','BRA',96291),
+(435,'Parnamirim','BRA',96210),
+(436,'Jacobina','BRA',96131),
+(437,'Coronel Fabriciano','BRA',95933),
+(438,'Birigui','BRA',94685),
+(439,'Tatuí','BRA',93897),
+(440,'Ji-Paraná','BRA',93346),
+(441,'Bacabal','BRA',93121),
+(442,'Cametá','BRA',92779),
+(443,'Guaíba','BRA',92224),
+(444,'São Lourenço da Mata','BRA',91999),
+(445,'Santana do Livramento','BRA',91779),
+(446,'Votorantim','BRA',91777),
+(447,'Campo Largo','BRA',91203),
+(448,'Patos','BRA',90519),
+(449,'Ituiutaba','BRA',90507),
+(450,'Corumbá','BRA',90111),
+(451,'Palhoça','BRA',89465),
+(452,'Barra do Piraí','BRA',89388),
+(453,'Bento Gonçalves','BRA',89254),
+(454,'Poá','BRA',89236),
+(455,'Ãguas Lindas de Goiás','BRA',89200),
+(456,'London','GBR',7285000),
+(457,'Birmingham','GBR',1013000),
+(458,'Glasgow','GBR',619680),
+(459,'Liverpool','GBR',461000),
+(460,'Edinburgh','GBR',450180),
+(461,'Sheffield','GBR',431607),
+(462,'Manchester','GBR',430000),
+(463,'Leeds','GBR',424194),
+(464,'Bristol','GBR',402000),
+(465,'Cardiff','GBR',321000),
+(466,'Coventry','GBR',304000),
+(467,'Leicester','GBR',294000),
+(468,'Bradford','GBR',289376),
+(469,'Belfast','GBR',287500),
+(470,'Nottingham','GBR',287000),
+(471,'Kingston upon Hull','GBR',262000),
+(472,'Plymouth','GBR',253000),
+(473,'Stoke-on-Trent','GBR',252000),
+(474,'Wolverhampton','GBR',242000),
+(475,'Derby','GBR',236000),
+(476,'Swansea','GBR',230000),
+(477,'Southampton','GBR',216000),
+(478,'Aberdeen','GBR',213070),
+(479,'Northampton','GBR',196000),
+(480,'Dudley','GBR',192171),
+(481,'Portsmouth','GBR',190000),
+(482,'Newcastle upon Tyne','GBR',189150),
+(483,'Sunderland','GBR',183310),
+(484,'Luton','GBR',183000),
+(485,'Swindon','GBR',180000),
+(486,'Southend-on-Sea','GBR',176000),
+(487,'Walsall','GBR',174739),
+(488,'Bournemouth','GBR',162000),
+(489,'Peterborough','GBR',156000),
+(490,'Brighton','GBR',156124),
+(491,'Blackpool','GBR',151000),
+(492,'Dundee','GBR',146690),
+(493,'West Bromwich','GBR',146386),
+(494,'Reading','GBR',148000),
+(495,'Oldbury/Smethwick (Warley)','GBR',145542),
+(496,'Middlesbrough','GBR',145000),
+(497,'Huddersfield','GBR',143726),
+(498,'Oxford','GBR',144000),
+(499,'Poole','GBR',141000),
+(500,'Bolton','GBR',139020),
+(501,'Blackburn','GBR',140000),
+(502,'Newport','GBR',139000),
+(503,'Preston','GBR',135000),
+(504,'Stockport','GBR',132813),
+(505,'Norwich','GBR',124000),
+(506,'Rotherham','GBR',121380),
+(507,'Cambridge','GBR',121000),
+(508,'Watford','GBR',113080),
+(509,'Ipswich','GBR',114000),
+(510,'Slough','GBR',112000),
+(511,'Exeter','GBR',111000),
+(512,'Cheltenham','GBR',106000),
+(513,'Gloucester','GBR',107000),
+(514,'Saint Helens','GBR',106293),
+(515,'Sutton Coldfield','GBR',106001),
+(516,'York','GBR',104425),
+(517,'Oldham','GBR',103931),
+(518,'Basildon','GBR',100924),
+(519,'Worthing','GBR',100000),
+(520,'Chelmsford','GBR',97451),
+(521,'Colchester','GBR',96063),
+(522,'Crawley','GBR',97000),
+(523,'Gillingham','GBR',92000),
+(524,'Solihull','GBR',94531),
+(525,'Rochdale','GBR',94313),
+(526,'Birkenhead','GBR',93087),
+(527,'Worcester','GBR',95000),
+(528,'Hartlepool','GBR',92000),
+(529,'Halifax','GBR',91069),
+(530,'Woking/Byfleet','GBR',92000),
+(531,'Southport','GBR',90959),
+(532,'Maidstone','GBR',90878),
+(533,'Eastbourne','GBR',90000),
+(534,'Grimsby','GBR',89000),
+(535,'Saint Helier','GBR',27523),
+(536,'Douglas','GBR',23487),
+(537,'Road Town','VGB',8000),
+(538,'Bandar Seri Begawan','BRN',21484),
+(539,'Sofija','BGR',1122302),
+(540,'Plovdiv','BGR',342584),
+(541,'Varna','BGR',299801),
+(542,'Burgas','BGR',195255),
+(543,'Ruse','BGR',166467),
+(544,'Stara Zagora','BGR',147939),
+(545,'Pleven','BGR',121952),
+(546,'Sliven','BGR',105530),
+(547,'Dobric','BGR',100399),
+(548,'Šumen','BGR',94686),
+(549,'Ouagadougou','BFA',824000),
+(550,'Bobo-Dioulasso','BFA',300000),
+(551,'Koudougou','BFA',105000),
+(552,'Bujumbura','BDI',300000),
+(553,'George Town','CYM',19600),
+(554,'Santiago de Chile','CHL',4703954),
+(555,'Puente Alto','CHL',386236),
+(556,'Viña del Mar','CHL',312493),
+(557,'Valparaíso','CHL',293800),
+(558,'Talcahuano','CHL',277752),
+(559,'Antofagasta','CHL',251429),
+(560,'San Bernardo','CHL',241910),
+(561,'Temuco','CHL',233041),
+(562,'Concepción','CHL',217664),
+(563,'Rancagua','CHL',212977),
+(564,'Arica','CHL',189036),
+(565,'Talca','CHL',187557),
+(566,'Chillán','CHL',178182),
+(567,'Iquique','CHL',177892),
+(568,'Los Angeles','CHL',158215),
+(569,'Puerto Montt','CHL',152194),
+(570,'Coquimbo','CHL',143353),
+(571,'Osorno','CHL',141468),
+(572,'La Serena','CHL',137409),
+(573,'Calama','CHL',137265),
+(574,'Valdivia','CHL',133106),
+(575,'Punta Arenas','CHL',125631),
+(576,'Copiapó','CHL',120128),
+(577,'Quilpué','CHL',118857),
+(578,'Curicó','CHL',115766),
+(579,'Ovalle','CHL',94854),
+(580,'Coronel','CHL',93061),
+(581,'San Pedro de la Paz','CHL',91684),
+(582,'Melipilla','CHL',91056),
+(583,'Avarua','COK',11900),
+(584,'San José','CRI',339131),
+(585,'Djibouti','DJI',383000),
+(586,'Roseau','DMA',16243),
+(587,'Santo Domingo de Guzmán','DOM',1609966),
+(588,'Santiago de los Caballeros','DOM',365463),
+(589,'La Romana','DOM',140204),
+(590,'San Pedro de Macorís','DOM',124735),
+(591,'San Francisco de Macorís','DOM',108485),
+(592,'San Felipe de Puerto Plata','DOM',89423),
+(593,'Guayaquil','ECU',2070040),
+(594,'Quito','ECU',1573458),
+(595,'Cuenca','ECU',270353),
+(596,'Machala','ECU',210368),
+(597,'Santo Domingo de los Colorados','ECU',202111),
+(598,'Portoviejo','ECU',176413),
+(599,'Ambato','ECU',169612),
+(600,'Manta','ECU',164739);
+INSERT INTO City VALUES
+(601,'Duran [Eloy Alfaro]','ECU',152514),
+(602,'Ibarra','ECU',130643),
+(603,'Quevedo','ECU',129631),
+(604,'Milagro','ECU',124177),
+(605,'Loja','ECU',123875),
+(606,'Ríobamba','ECU',123163),
+(607,'Esmeraldas','ECU',123045),
+(608,'Cairo','EGY',6789479),
+(609,'Alexandria','EGY',3328196),
+(610,'Giza','EGY',2221868),
+(611,'Shubra al-Khayma','EGY',870716),
+(612,'Port Said','EGY',469533),
+(613,'Suez','EGY',417610),
+(614,'al-Mahallat al-Kubra','EGY',395402),
+(615,'Tanta','EGY',371010),
+(616,'al-Mansura','EGY',369621),
+(617,'Luxor','EGY',360503),
+(618,'Asyut','EGY',343498),
+(619,'Bahtim','EGY',275807),
+(620,'Zagazig','EGY',267351),
+(621,'al-Faiyum','EGY',260964),
+(622,'Ismailia','EGY',254477),
+(623,'Kafr al-Dawwar','EGY',231978),
+(624,'Assuan','EGY',219017),
+(625,'Damanhur','EGY',212203),
+(626,'al-Minya','EGY',201360),
+(627,'Bani Suwayf','EGY',172032),
+(628,'Qina','EGY',171275),
+(629,'Sawhaj','EGY',170125),
+(630,'Shibin al-Kawm','EGY',159909),
+(631,'Bulaq al-Dakrur','EGY',148787),
+(632,'Banha','EGY',145792),
+(633,'Warraq al-Arab','EGY',127108),
+(634,'Kafr al-Shaykh','EGY',124819),
+(635,'Mallawi','EGY',119283),
+(636,'Bilbays','EGY',113608),
+(637,'Mit Ghamr','EGY',101801),
+(638,'al-Arish','EGY',100447),
+(639,'Talkha','EGY',97700),
+(640,'Qalyub','EGY',97200),
+(641,'Jirja','EGY',95400),
+(642,'Idfu','EGY',94200),
+(643,'al-Hawamidiya','EGY',91700),
+(644,'Disuq','EGY',91300),
+(645,'San Salvador','SLV',415346),
+(646,'Santa Ana','SLV',139389),
+(647,'Mejicanos','SLV',138800),
+(648,'Soyapango','SLV',129800),
+(649,'San Miguel','SLV',127696),
+(650,'Nueva San Salvador','SLV',98400),
+(651,'Apopa','SLV',88800),
+(652,'Asmara','ERI',431000),
+(653,'Madrid','ESP',2879052),
+(654,'Barcelona','ESP',1503451),
+(655,'Valencia','ESP',739412),
+(656,'Sevilla','ESP',701927),
+(657,'Zaragoza','ESP',603367),
+(658,'Málaga','ESP',530553),
+(659,'Bilbao','ESP',357589),
+(660,'Las Palmas de Gran Canaria','ESP',354757),
+(661,'Murcia','ESP',353504),
+(662,'Palma de Mallorca','ESP',326993),
+(663,'Valladolid','ESP',319998),
+(664,'Córdoba','ESP',311708),
+(665,'Vigo','ESP',283670),
+(666,'Alicante [Alacant]','ESP',272432),
+(667,'Gijón','ESP',267980),
+(668,'L´Hospitalet de Llobregat','ESP',247986),
+(669,'Granada','ESP',244767),
+(670,'A Coruña (La Coruña)','ESP',243402),
+(671,'Vitoria-Gasteiz','ESP',217154),
+(672,'Santa Cruz de Tenerife','ESP',213050),
+(673,'Badalona','ESP',209635),
+(674,'Oviedo','ESP',200453),
+(675,'Móstoles','ESP',195351),
+(676,'Elche [Elx]','ESP',193174),
+(677,'Sabadell','ESP',184859),
+(678,'Santander','ESP',184165),
+(679,'Jerez de la Frontera','ESP',182660),
+(680,'Pamplona [Iruña]','ESP',180483),
+(681,'Donostia-San Sebastián','ESP',179208),
+(682,'Cartagena','ESP',177709),
+(683,'Leganés','ESP',173163),
+(684,'Fuenlabrada','ESP',171173),
+(685,'Almería','ESP',169027),
+(686,'Terrassa','ESP',168695),
+(687,'Alcalá de Henares','ESP',164463),
+(688,'Burgos','ESP',162802),
+(689,'Salamanca','ESP',158720),
+(690,'Albacete','ESP',147527),
+(691,'Getafe','ESP',145371),
+(692,'Cádiz','ESP',142449),
+(693,'Alcorcón','ESP',142048),
+(694,'Huelva','ESP',140583),
+(695,'León','ESP',139809),
+(696,'Castellón de la Plana [Castell','ESP',139712),
+(697,'Badajoz','ESP',136613),
+(698,'[San Cristóbal de] la Laguna','ESP',127945),
+(699,'Logroño','ESP',127093),
+(700,'Santa Coloma de Gramenet','ESP',120802),
+(701,'Tarragona','ESP',113016),
+(702,'Lleida (Lérida)','ESP',112207),
+(703,'Jaén','ESP',109247),
+(704,'Ourense (Orense)','ESP',109120),
+(705,'Mataró','ESP',104095),
+(706,'Algeciras','ESP',103106),
+(707,'Marbella','ESP',101144),
+(708,'Barakaldo','ESP',98212),
+(709,'Dos Hermanas','ESP',94591),
+(710,'Santiago de Compostela','ESP',93745),
+(711,'Torrejón de Ardoz','ESP',92262),
+(712,'Cape Town','ZAF',2352121),
+(713,'Soweto','ZAF',904165),
+(714,'Johannesburg','ZAF',756653),
+(715,'Port Elizabeth','ZAF',752319),
+(716,'Pretoria','ZAF',658630),
+(717,'Inanda','ZAF',634065),
+(718,'Durban','ZAF',566120),
+(719,'Vanderbijlpark','ZAF',468931),
+(720,'Kempton Park','ZAF',442633),
+(721,'Alberton','ZAF',410102),
+(722,'Pinetown','ZAF',378810),
+(723,'Pietermaritzburg','ZAF',370190),
+(724,'Benoni','ZAF',365467),
+(725,'Randburg','ZAF',341288),
+(726,'Umlazi','ZAF',339233),
+(727,'Bloemfontein','ZAF',334341),
+(728,'Vereeniging','ZAF',328535),
+(729,'Wonderboom','ZAF',283289),
+(730,'Roodepoort','ZAF',279340),
+(731,'Boksburg','ZAF',262648),
+(732,'Klerksdorp','ZAF',261911),
+(733,'Soshanguve','ZAF',242727),
+(734,'Newcastle','ZAF',222993),
+(735,'East London','ZAF',221047),
+(736,'Welkom','ZAF',203296),
+(737,'Kimberley','ZAF',197254),
+(738,'Uitenhage','ZAF',192120),
+(739,'Chatsworth','ZAF',189885),
+(740,'Mdantsane','ZAF',182639),
+(741,'Krugersdorp','ZAF',181503),
+(742,'Botshabelo','ZAF',177971),
+(743,'Brakpan','ZAF',171363),
+(744,'Witbank','ZAF',167183),
+(745,'Oberholzer','ZAF',164367),
+(746,'Germiston','ZAF',164252),
+(747,'Springs','ZAF',162072),
+(748,'Westonaria','ZAF',159632),
+(749,'Randfontein','ZAF',120838),
+(750,'Paarl','ZAF',105768),
+(751,'Potchefstroom','ZAF',101817),
+(752,'Rustenburg','ZAF',97008),
+(753,'Nigel','ZAF',96734),
+(754,'George','ZAF',93818),
+(755,'Ladysmith','ZAF',89292),
+(756,'Addis Abeba','ETH',2495000),
+(757,'Dire Dawa','ETH',164851),
+(758,'Nazret','ETH',127842),
+(759,'Gonder','ETH',112249),
+(760,'Dese','ETH',97314),
+(761,'Mekele','ETH',96938),
+(762,'Bahir Dar','ETH',96140),
+(763,'Stanley','FLK',1636),
+(764,'Suva','FJI',77366),
+(765,'Quezon','PHL',2173831),
+(766,'Manila','PHL',1581082),
+(767,'Kalookan','PHL',1177604),
+(768,'Davao','PHL',1147116),
+(769,'Cebu','PHL',718821),
+(770,'Zamboanga','PHL',601794),
+(771,'Pasig','PHL',505058),
+(772,'Valenzuela','PHL',485433),
+(773,'Las Piñas','PHL',472780),
+(774,'Antipolo','PHL',470866),
+(775,'Taguig','PHL',467375),
+(776,'Cagayan de Oro','PHL',461877),
+(777,'Parañaque','PHL',449811),
+(778,'Makati','PHL',444867),
+(779,'Bacolod','PHL',429076),
+(780,'General Santos','PHL',411822),
+(781,'Marikina','PHL',391170),
+(782,'Dasmariñas','PHL',379520),
+(783,'Muntinlupa','PHL',379310),
+(784,'Iloilo','PHL',365820),
+(785,'Pasay','PHL',354908),
+(786,'Malabon','PHL',338855),
+(787,'San José del Monte','PHL',315807),
+(788,'Bacoor','PHL',305699),
+(789,'Iligan','PHL',285061),
+(790,'Calamba','PHL',281146),
+(791,'Mandaluyong','PHL',278474),
+(792,'Butuan','PHL',267279),
+(793,'Angeles','PHL',263971),
+(794,'Tarlac','PHL',262481),
+(795,'Mandaue','PHL',259728),
+(796,'Baguio','PHL',252386),
+(797,'Batangas','PHL',247588),
+(798,'Cainta','PHL',242511),
+(799,'San Pedro','PHL',231403),
+ (800,'Navotas','PHL',230403);
+INSERT INTO City VALUES
+(801,'Cabanatuan','PHL',222859),
+(802,'San Fernando','PHL',221857),
+(803,'Lipa','PHL',218447),
+(804,'Lapu-Lapu','PHL',217019),
+(805,'San Pablo','PHL',207927),
+(806,'Biñan','PHL',201186),
+(807,'Taytay','PHL',198183),
+(808,'Lucena','PHL',196075),
+(809,'Imus','PHL',195482),
+(810,'Olongapo','PHL',194260),
+(811,'Binangonan','PHL',187691),
+(812,'Santa Rosa','PHL',185633),
+(813,'Tagum','PHL',179531),
+(814,'Tacloban','PHL',178639),
+(815,'Malolos','PHL',175291),
+(816,'Mabalacat','PHL',171045),
+(817,'Cotabato','PHL',163849),
+(818,'Meycauayan','PHL',163037),
+(819,'Puerto Princesa','PHL',161912),
+(820,'Legazpi','PHL',157010),
+(821,'Silang','PHL',156137),
+(822,'Ormoc','PHL',154297),
+(823,'San Carlos','PHL',154264),
+(824,'Kabankalan','PHL',149769),
+(825,'Talisay','PHL',148110),
+(826,'Valencia','PHL',147924),
+(827,'Calbayog','PHL',147187),
+(828,'Santa Maria','PHL',144282),
+(829,'Pagadian','PHL',142515),
+(830,'Cadiz','PHL',141954),
+(831,'Bago','PHL',141721),
+(832,'Toledo','PHL',141174),
+(833,'Naga','PHL',137810),
+(834,'San Mateo','PHL',135603),
+(835,'Panabo','PHL',133950),
+(836,'Koronadal','PHL',133786),
+(837,'Marawi','PHL',131090),
+(838,'Dagupan','PHL',130328),
+(839,'Sagay','PHL',129765),
+(840,'Roxas','PHL',126352),
+(841,'Lubao','PHL',125699),
+(842,'Digos','PHL',125171),
+(843,'San Miguel','PHL',123824),
+(844,'Malaybalay','PHL',123672),
+(845,'Tuguegarao','PHL',120645),
+(846,'Ilagan','PHL',119990),
+(847,'Baliuag','PHL',119675),
+(848,'Surigao','PHL',118534),
+(849,'San Carlos','PHL',118259),
+(850,'San Juan del Monte','PHL',117680),
+(851,'Tanauan','PHL',117539),
+(852,'Concepcion','PHL',115171),
+(853,'Rodriguez (Montalban)','PHL',115167),
+(854,'Sariaya','PHL',114568),
+(855,'Malasiqui','PHL',113190),
+(856,'General Mariano Alvarez','PHL',112446),
+(857,'Urdaneta','PHL',111582),
+(858,'Hagonoy','PHL',111425),
+(859,'San Jose','PHL',111009),
+(860,'Polomolok','PHL',110709),
+(861,'Santiago','PHL',110531),
+(862,'Tanza','PHL',110517),
+(863,'Ozamis','PHL',110420),
+(864,'Mexico','PHL',109481),
+(865,'San Jose','PHL',108254),
+(866,'Silay','PHL',107722),
+(867,'General Trias','PHL',107691),
+(868,'Tabaco','PHL',107166),
+(869,'Cabuyao','PHL',106630),
+(870,'Calapan','PHL',105910),
+(871,'Mati','PHL',105908),
+(872,'Midsayap','PHL',105760),
+(873,'Cauayan','PHL',103952),
+(874,'Gingoog','PHL',102379),
+(875,'Dumaguete','PHL',102265),
+(876,'San Fernando','PHL',102082),
+(877,'Arayat','PHL',101792),
+(878,'Bayawan (Tulong)','PHL',101391),
+(879,'Kidapawan','PHL',101205),
+(880,'Daraga (Locsin)','PHL',101031),
+(881,'Marilao','PHL',101017),
+(882,'Malita','PHL',100000),
+(883,'Dipolog','PHL',99862),
+(884,'Cavite','PHL',99367),
+(885,'Danao','PHL',98781),
+(886,'Bislig','PHL',97860),
+(887,'Talavera','PHL',97329),
+(888,'Guagua','PHL',96858),
+(889,'Bayambang','PHL',96609),
+(890,'Nasugbu','PHL',96113),
+(891,'Baybay','PHL',95630),
+(892,'Capas','PHL',95219),
+(893,'Sultan Kudarat','PHL',94861),
+(894,'Laoag','PHL',94466),
+(895,'Bayugan','PHL',93623),
+(896,'Malungon','PHL',93232),
+(897,'Santa Cruz','PHL',92694),
+(898,'Sorsogon','PHL',92512),
+(899,'Candelaria','PHL',92429),
+(900,'Ligao','PHL',90603),
+(901,'Tórshavn','FRO',14542),
+(902,'Libreville','GAB',419000),
+(903,'Serekunda','GMB',102600),
+(904,'Banjul','GMB',42326),
+(905,'Tbilisi','GEO',1235200),
+(906,'Kutaisi','GEO',240900),
+(907,'Rustavi','GEO',155400),
+(908,'Batumi','GEO',137700),
+(909,'Sohumi','GEO',111700),
+(910,'Accra','GHA',1070000),
+(911,'Kumasi','GHA',385192),
+(912,'Tamale','GHA',151069),
+(913,'Tema','GHA',109975),
+(914,'Sekondi-Takoradi','GHA',103653),
+(915,'Gibraltar','GIB',27025),
+(916,'Saint George´s','GRD',4621),
+(917,'Nuuk','GRL',13445),
+(918,'Les Abymes','GLP',62947),
+(919,'Basse-Terre','GLP',12433),
+(920,'Tamuning','GUM',9500),
+(921,'Agaña','GUM',1139),
+(922,'Ciudad de Guatemala','GTM',823301),
+(923,'Mixco','GTM',209791),
+(924,'Villa Nueva','GTM',101295),
+(925,'Quetzaltenango','GTM',90801),
+(926,'Conakry','GIN',1090610),
+(927,'Bissau','GNB',241000),
+(928,'Georgetown','GUY',254000),
+(929,'Port-au-Prince','HTI',884472),
+(930,'Carrefour','HTI',290204),
+(931,'Delmas','HTI',240429),
+(932,'Le-Cap-Haïtien','HTI',102233),
+(933,'Tegucigalpa','HND',813900),
+(934,'San Pedro Sula','HND',383900),
+(935,'La Ceiba','HND',89200),
+(936,'Kowloon and New Kowloon','HKG',1987996),
+(937,'Victoria','HKG',1312637),
+(938,'Longyearbyen','SJM',1438),
+(939,'Jakarta','IDN',9604900),
+(940,'Surabaya','IDN',2663820),
+(941,'Bandung','IDN',2429000),
+(942,'Medan','IDN',1843919),
+(943,'Palembang','IDN',1222764),
+(944,'Tangerang','IDN',1198300),
+(945,'Semarang','IDN',1104405),
+(946,'Ujung Pandang','IDN',1060257),
+(947,'Malang','IDN',716862),
+(948,'Bandar Lampung','IDN',680332),
+(949,'Bekasi','IDN',644300),
+(950,'Padang','IDN',534474),
+(951,'Surakarta','IDN',518600),
+(952,'Banjarmasin','IDN',482931),
+(953,'Pekan Baru','IDN',438638),
+(954,'Denpasar','IDN',435000),
+(955,'Yogyakarta','IDN',418944),
+(956,'Pontianak','IDN',409632),
+(957,'Samarinda','IDN',399175),
+(958,'Jambi','IDN',385201),
+(959,'Depok','IDN',365200),
+(960,'Cimahi','IDN',344600),
+(961,'Balikpapan','IDN',338752),
+(962,'Manado','IDN',332288),
+(963,'Mataram','IDN',306600),
+(964,'Pekalongan','IDN',301504),
+(965,'Tegal','IDN',289744),
+(966,'Bogor','IDN',285114),
+(967,'Ciputat','IDN',270800),
+(968,'Pondokgede','IDN',263200),
+(969,'Cirebon','IDN',254406),
+(970,'Kediri','IDN',253760),
+(971,'Ambon','IDN',249312),
+(972,'Jember','IDN',218500),
+(973,'Cilacap','IDN',206900),
+(974,'Cimanggis','IDN',205100),
+(975,'Pematang Siantar','IDN',203056),
+(976,'Purwokerto','IDN',202500),
+(977,'Ciomas','IDN',187400),
+(978,'Tasikmalaya','IDN',179800),
+(979,'Madiun','IDN',171532),
+(980,'Bengkulu','IDN',146439),
+(981,'Karawang','IDN',145000),
+(982,'Banda Aceh','IDN',143409),
+(983,'Palu','IDN',142800),
+(984,'Pasuruan','IDN',134019),
+(985,'Kupang','IDN',129300),
+(986,'Tebing Tinggi','IDN',129300),
+(987,'Percut Sei Tuan','IDN',129000),
+(988,'Binjai','IDN',127222),
+(989,'Sukabumi','IDN',125766),
+(990,'Waru','IDN',124300),
+(991,'Pangkal Pinang','IDN',124000),
+(992,'Magelang','IDN',123800),
+(993,'Blitar','IDN',122600),
+(994,'Serang','IDN',122400),
+(995,'Probolinggo','IDN',120770),
+(996,'Cilegon','IDN',117000),
+(997,'Cianjur','IDN',114300),
+(998,'Ciparay','IDN',111500),
+(999,'Lhokseumawe','IDN',109600),
+(1000,'Taman','IDN',107000);
+INSERT INTO City VALUES
+(1001,'Depok','IDN',106800),
+(1002,'Citeureup','IDN',105100),
+(1003,'Pemalang','IDN',103500),
+(1004,'Klaten','IDN',103300),
+(1005,'Salatiga','IDN',103000),
+(1006,'Cibinong','IDN',101300),
+(1007,'Palangka Raya','IDN',99693),
+(1008,'Mojokerto','IDN',96626),
+(1009,'Purwakarta','IDN',95900),
+(1010,'Garut','IDN',95800),
+(1011,'Kudus','IDN',95300),
+(1012,'Kendari','IDN',94800),
+(1013,'Jaya Pura','IDN',94700),
+(1014,'Gorontalo','IDN',94058),
+(1015,'Majalaya','IDN',93200),
+(1016,'Pondok Aren','IDN',92700),
+(1017,'Jombang','IDN',92600),
+(1018,'Sunggal','IDN',92300),
+(1019,'Batam','IDN',91871),
+(1020,'Padang Sidempuan','IDN',91200),
+(1021,'Sawangan','IDN',91100),
+(1022,'Banyuwangi','IDN',89900),
+(1023,'Tanjung Pinang','IDN',89900),
+(1024,'Mumbai (Bombay)','IND',10500000),
+(1025,'Delhi','IND',7206704),
+(1026,'Calcutta [Kolkata]','IND',4399819),
+(1027,'Chennai (Madras)','IND',3841396),
+(1028,'Hyderabad','IND',2964638),
+(1029,'Ahmedabad','IND',2876710),
+(1030,'Bangalore','IND',2660088),
+(1031,'Kanpur','IND',1874409),
+(1032,'Nagpur','IND',1624752),
+(1033,'Lucknow','IND',1619115),
+(1034,'Pune','IND',1566651),
+(1035,'Surat','IND',1498817),
+(1036,'Jaipur','IND',1458483),
+(1037,'Indore','IND',1091674),
+(1038,'Bhopal','IND',1062771),
+(1039,'Ludhiana','IND',1042740),
+(1040,'Vadodara (Baroda)','IND',1031346),
+(1041,'Kalyan','IND',1014557),
+(1042,'Madurai','IND',977856),
+(1043,'Haora (Howrah)','IND',950435),
+(1044,'Varanasi (Benares)','IND',929270),
+(1045,'Patna','IND',917243),
+(1046,'Srinagar','IND',892506),
+(1047,'Agra','IND',891790),
+(1048,'Coimbatore','IND',816321),
+(1049,'Thane (Thana)','IND',803389),
+(1050,'Allahabad','IND',792858),
+(1051,'Meerut','IND',753778),
+(1052,'Vishakhapatnam','IND',752037),
+(1053,'Jabalpur','IND',741927),
+(1054,'Amritsar','IND',708835),
+(1055,'Faridabad','IND',703592),
+(1056,'Vijayawada','IND',701827),
+(1057,'Gwalior','IND',690765),
+(1058,'Jodhpur','IND',666279),
+(1059,'Nashik (Nasik)','IND',656925),
+(1060,'Hubli-Dharwad','IND',648298),
+(1061,'Solapur (Sholapur)','IND',604215),
+(1062,'Ranchi','IND',599306),
+(1063,'Bareilly','IND',587211),
+(1064,'Guwahati (Gauhati)','IND',584342),
+(1065,'Shambajinagar (Aurangabad)','IND',573272),
+(1066,'Cochin (Kochi)','IND',564589),
+(1067,'Rajkot','IND',559407),
+(1068,'Kota','IND',537371),
+(1069,'Thiruvananthapuram (Trivandrum','IND',524006),
+(1070,'Pimpri-Chinchwad','IND',517083),
+(1071,'Jalandhar (Jullundur)','IND',509510),
+(1072,'Gorakhpur','IND',505566),
+(1073,'Chandigarh','IND',504094),
+(1074,'Mysore','IND',480692),
+(1075,'Aligarh','IND',480520),
+(1076,'Guntur','IND',471051),
+(1077,'Jamshedpur','IND',460577),
+(1078,'Ghaziabad','IND',454156),
+(1079,'Warangal','IND',447657),
+(1080,'Raipur','IND',438639),
+(1081,'Moradabad','IND',429214),
+(1082,'Durgapur','IND',425836),
+(1083,'Amravati','IND',421576),
+(1084,'Calicut (Kozhikode)','IND',419831),
+(1085,'Bikaner','IND',416289),
+(1086,'Bhubaneswar','IND',411542),
+(1087,'Kolhapur','IND',406370),
+(1088,'Kataka (Cuttack)','IND',403418),
+(1089,'Ajmer','IND',402700),
+(1090,'Bhavnagar','IND',402338),
+(1091,'Tiruchirapalli','IND',387223),
+(1092,'Bhilai','IND',386159),
+(1093,'Bhiwandi','IND',379070),
+(1094,'Saharanpur','IND',374945),
+(1095,'Ulhasnagar','IND',369077),
+(1096,'Salem','IND',366712),
+(1097,'Ujjain','IND',362266),
+(1098,'Malegaon','IND',342595),
+(1099,'Jamnagar','IND',341637),
+(1100,'Bokaro Steel City','IND',333683),
+(1101,'Akola','IND',328034),
+(1102,'Belgaum','IND',326399),
+(1103,'Rajahmundry','IND',324851),
+(1104,'Nellore','IND',316606),
+(1105,'Udaipur','IND',308571),
+(1106,'New Bombay','IND',307297),
+(1107,'Bhatpara','IND',304952),
+(1108,'Gulbarga','IND',304099),
+(1109,'New Delhi','IND',301297),
+(1110,'Jhansi','IND',300850),
+(1111,'Gaya','IND',291675),
+(1112,'Kakinada','IND',279980),
+(1113,'Dhule (Dhulia)','IND',278317),
+(1114,'Panihati','IND',275990),
+(1115,'Nanded (Nander)','IND',275083),
+(1116,'Mangalore','IND',273304),
+(1117,'Dehra Dun','IND',270159),
+(1118,'Kamarhati','IND',266889),
+(1119,'Davangere','IND',266082),
+(1120,'Asansol','IND',262188),
+(1121,'Bhagalpur','IND',253225),
+(1122,'Bellary','IND',245391),
+(1123,'Barddhaman (Burdwan)','IND',245079),
+(1124,'Rampur','IND',243742),
+(1125,'Jalgaon','IND',242193),
+(1126,'Muzaffarpur','IND',241107),
+(1127,'Nizamabad','IND',241034),
+(1128,'Muzaffarnagar','IND',240609),
+(1129,'Patiala','IND',238368),
+(1130,'Shahjahanpur','IND',237713),
+(1131,'Kurnool','IND',236800),
+(1132,'Tiruppur (Tirupper)','IND',235661),
+(1133,'Rohtak','IND',233400),
+(1134,'South Dum Dum','IND',232811),
+(1135,'Mathura','IND',226691),
+(1136,'Chandrapur','IND',226105),
+(1137,'Barahanagar (Baranagar)','IND',224821),
+(1138,'Darbhanga','IND',218391),
+(1139,'Siliguri (Shiliguri)','IND',216950),
+(1140,'Raurkela','IND',215489),
+(1141,'Ambattur','IND',215424),
+(1142,'Panipat','IND',215218),
+(1143,'Firozabad','IND',215128),
+(1144,'Ichalkaranji','IND',214950),
+(1145,'Jammu','IND',214737),
+(1146,'Ramagundam','IND',214384),
+(1147,'Eluru','IND',212866),
+(1148,'Brahmapur','IND',210418),
+(1149,'Alwar','IND',205086),
+(1150,'Pondicherry','IND',203065),
+(1151,'Thanjavur','IND',202013),
+(1152,'Bihar Sharif','IND',201323),
+(1153,'Tuticorin','IND',199854),
+(1154,'Imphal','IND',198535),
+(1155,'Latur','IND',197408),
+(1156,'Sagar','IND',195346),
+(1157,'Farrukhabad-cum-Fatehgarh','IND',194567),
+(1158,'Sangli','IND',193197),
+(1159,'Parbhani','IND',190255),
+(1160,'Nagar Coil','IND',190084),
+(1161,'Bijapur','IND',186939),
+(1162,'Kukatpalle','IND',185378),
+(1163,'Bally','IND',184474),
+(1164,'Bhilwara','IND',183965),
+(1165,'Ratlam','IND',183375),
+(1166,'Avadi','IND',183215),
+(1167,'Dindigul','IND',182477),
+(1168,'Ahmadnagar','IND',181339),
+(1169,'Bilaspur','IND',179833),
+(1170,'Shimoga','IND',179258),
+(1171,'Kharagpur','IND',177989),
+(1172,'Mira Bhayandar','IND',175372),
+(1173,'Vellore','IND',175061),
+(1174,'Jalna','IND',174985),
+(1175,'Burnpur','IND',174933),
+(1176,'Anantapur','IND',174924),
+(1177,'Allappuzha (Alleppey)','IND',174666),
+(1178,'Tirupati','IND',174369),
+(1179,'Karnal','IND',173751),
+(1180,'Burhanpur','IND',172710),
+(1181,'Hisar (Hissar)','IND',172677),
+(1182,'Tiruvottiyur','IND',172562),
+(1183,'Mirzapur-cum-Vindhyachal','IND',169336),
+(1184,'Secunderabad','IND',167461),
+(1185,'Nadiad','IND',167051),
+(1186,'Dewas','IND',164364),
+(1187,'Murwara (Katni)','IND',163431),
+(1188,'Ganganagar','IND',161482),
+(1189,'Vizianagaram','IND',160359),
+(1190,'Erode','IND',159232),
+(1191,'Machilipatnam (Masulipatam)','IND',159110),
+(1192,'Bhatinda (Bathinda)','IND',159042),
+(1193,'Raichur','IND',157551),
+(1194,'Agartala','IND',157358),
+(1195,'Arrah (Ara)','IND',157082),
+(1196,'Satna','IND',156630),
+(1197,'Lalbahadur Nagar','IND',155500),
+(1198,'Aizawl','IND',155240),
+(1199,'Uluberia','IND',155172),
+(1200,'Katihar','IND',154367);
+INSERT INTO City VALUES
+(1201,'Cuddalore','IND',153086),
+(1202,'Hugli-Chinsurah','IND',151806),
+(1203,'Dhanbad','IND',151789),
+(1204,'Raiganj','IND',151045),
+(1205,'Sambhal','IND',150869),
+(1206,'Durg','IND',150645),
+(1207,'Munger (Monghyr)','IND',150112),
+(1208,'Kanchipuram','IND',150100),
+(1209,'North Dum Dum','IND',149965),
+(1210,'Karimnagar','IND',148583),
+(1211,'Bharatpur','IND',148519),
+(1212,'Sikar','IND',148272),
+(1213,'Hardwar (Haridwar)','IND',147305),
+(1214,'Dabgram','IND',147217),
+(1215,'Morena','IND',147124),
+(1216,'Noida','IND',146514),
+(1217,'Hapur','IND',146262),
+(1218,'Bhusawal','IND',145143),
+(1219,'Khandwa','IND',145133),
+(1220,'Yamuna Nagar','IND',144346),
+(1221,'Sonipat (Sonepat)','IND',143922),
+(1222,'Tenali','IND',143726),
+(1223,'Raurkela Civil Township','IND',140408),
+(1224,'Kollam (Quilon)','IND',139852),
+(1225,'Kumbakonam','IND',139483),
+(1226,'Ingraj Bazar (English Bazar)','IND',139204),
+(1227,'Timkur','IND',138903),
+(1228,'Amroha','IND',137061),
+(1229,'Serampore','IND',137028),
+(1230,'Chapra','IND',136877),
+(1231,'Pali','IND',136842),
+(1232,'Maunath Bhanjan','IND',136697),
+(1233,'Adoni','IND',136182),
+(1234,'Jaunpur','IND',136062),
+(1235,'Tirunelveli','IND',135825),
+(1236,'Bahraich','IND',135400),
+(1237,'Gadag Betigeri','IND',134051),
+(1238,'Proddatur','IND',133914),
+(1239,'Chittoor','IND',133462),
+(1240,'Barrackpur','IND',133265),
+(1241,'Bharuch (Broach)','IND',133102),
+(1242,'Naihati','IND',132701),
+(1243,'Shillong','IND',131719),
+(1244,'Sambalpur','IND',131138),
+(1245,'Junagadh','IND',130484),
+(1246,'Rae Bareli','IND',129904),
+(1247,'Rewa','IND',128981),
+(1248,'Gurgaon','IND',128608),
+(1249,'Khammam','IND',127992),
+(1250,'Bulandshahr','IND',127201),
+(1251,'Navsari','IND',126089),
+(1252,'Malkajgiri','IND',126066),
+(1253,'Midnapore (Medinipur)','IND',125498),
+(1254,'Miraj','IND',125407),
+(1255,'Raj Nandgaon','IND',125371),
+(1256,'Alandur','IND',125244),
+(1257,'Puri','IND',125199),
+(1258,'Navadwip','IND',125037),
+(1259,'Sirsa','IND',125000),
+(1260,'Korba','IND',124501),
+(1261,'Faizabad','IND',124437),
+(1262,'Etawah','IND',124072),
+(1263,'Pathankot','IND',123930),
+(1264,'Gandhinagar','IND',123359),
+(1265,'Palghat (Palakkad)','IND',123289),
+(1266,'Veraval','IND',123000),
+(1267,'Hoshiarpur','IND',122705),
+(1268,'Ambala','IND',122596),
+(1269,'Sitapur','IND',121842),
+(1270,'Bhiwani','IND',121629),
+(1271,'Cuddapah','IND',121463),
+(1272,'Bhimavaram','IND',121314),
+(1273,'Krishnanagar','IND',121110),
+(1274,'Chandannagar','IND',120378),
+(1275,'Mandya','IND',120265),
+(1276,'Dibrugarh','IND',120127),
+(1277,'Nandyal','IND',119813),
+(1278,'Balurghat','IND',119796),
+(1279,'Neyveli','IND',118080),
+(1280,'Fatehpur','IND',117675),
+(1281,'Mahbubnagar','IND',116833),
+(1282,'Budaun','IND',116695),
+(1283,'Porbandar','IND',116671),
+(1284,'Silchar','IND',115483),
+(1285,'Berhampore (Baharampur)','IND',115144),
+(1286,'Purnea (Purnia)','IND',114912),
+(1287,'Bankura','IND',114876),
+(1288,'Rajapalaiyam','IND',114202),
+(1289,'Titagarh','IND',114085),
+(1290,'Halisahar','IND',114028),
+(1291,'Hathras','IND',113285),
+(1292,'Bhir (Bid)','IND',112434),
+(1293,'Pallavaram','IND',111866),
+(1294,'Anand','IND',110266),
+(1295,'Mango','IND',110024),
+(1296,'Santipur','IND',109956),
+(1297,'Bhind','IND',109755),
+(1298,'Gondiya','IND',109470),
+(1299,'Tiruvannamalai','IND',109196),
+(1300,'Yeotmal (Yavatmal)','IND',108578),
+(1301,'Kulti-Barakar','IND',108518),
+(1302,'Moga','IND',108304),
+(1303,'Shivapuri','IND',108277),
+(1304,'Bidar','IND',108016),
+(1305,'Guntakal','IND',107592),
+(1306,'Unnao','IND',107425),
+(1307,'Barasat','IND',107365),
+(1308,'Tambaram','IND',107187),
+(1309,'Abohar','IND',107163),
+(1310,'Pilibhit','IND',106605),
+(1311,'Valparai','IND',106523),
+(1312,'Gonda','IND',106078),
+(1313,'Surendranagar','IND',105973),
+(1314,'Qutubullapur','IND',105380),
+(1315,'Beawar','IND',105363),
+(1316,'Hindupur','IND',104651),
+(1317,'Gandhidham','IND',104585),
+(1318,'Haldwani-cum-Kathgodam','IND',104195),
+(1319,'Tellicherry (Thalassery)','IND',103579),
+(1320,'Wardha','IND',102985),
+(1321,'Rishra','IND',102649),
+(1322,'Bhuj','IND',102176),
+(1323,'Modinagar','IND',101660),
+(1324,'Gudivada','IND',101656),
+(1325,'Basirhat','IND',101409),
+(1326,'Uttarpara-Kotrung','IND',100867),
+(1327,'Ongole','IND',100836),
+(1328,'North Barrackpur','IND',100513),
+(1329,'Guna','IND',100490),
+(1330,'Haldia','IND',100347),
+(1331,'Habra','IND',100223),
+(1332,'Kanchrapara','IND',100194),
+(1333,'Tonk','IND',100079),
+(1334,'Champdani','IND',98818),
+(1335,'Orai','IND',98640),
+(1336,'Pudukkottai','IND',98619),
+(1337,'Sasaram','IND',98220),
+(1338,'Hazaribag','IND',97712),
+(1339,'Palayankottai','IND',97662),
+(1340,'Banda','IND',97227),
+(1341,'Godhra','IND',96813),
+(1342,'Hospet','IND',96322),
+(1343,'Ashoknagar-Kalyangarh','IND',96315),
+(1344,'Achalpur','IND',96216),
+(1345,'Patan','IND',96109),
+(1346,'Mandasor','IND',95758),
+(1347,'Damoh','IND',95661),
+(1348,'Satara','IND',95133),
+(1349,'Meerut Cantonment','IND',94876),
+(1350,'Dehri','IND',94526),
+(1351,'Delhi Cantonment','IND',94326),
+(1352,'Chhindwara','IND',93731),
+(1353,'Bansberia','IND',93447),
+(1354,'Nagaon','IND',93350),
+(1355,'Kanpur Cantonment','IND',93109),
+(1356,'Vidisha','IND',92917),
+(1357,'Bettiah','IND',92583),
+(1358,'Purulia','IND',92574),
+(1359,'Hassan','IND',90803),
+(1360,'Ambala Sadar','IND',90712),
+(1361,'Baidyabati','IND',90601),
+(1362,'Morvi','IND',90357),
+(1363,'Raigarh','IND',89166),
+(1364,'Vejalpur','IND',89053),
+(1365,'Baghdad','IRQ',4336000),
+(1366,'Mosul','IRQ',879000),
+(1367,'Irbil','IRQ',485968),
+(1368,'Kirkuk','IRQ',418624),
+(1369,'Basra','IRQ',406296),
+(1370,'al-Sulaymaniya','IRQ',364096),
+(1371,'al-Najaf','IRQ',309010),
+(1372,'Karbala','IRQ',296705),
+(1373,'al-Hilla','IRQ',268834),
+(1374,'al-Nasiriya','IRQ',265937),
+(1375,'al-Amara','IRQ',208797),
+(1376,'al-Diwaniya','IRQ',196519),
+(1377,'al-Ramadi','IRQ',192556),
+(1378,'al-Kut','IRQ',183183),
+(1379,'Baquba','IRQ',114516),
+(1380,'Teheran','IRN',6758845),
+(1381,'Mashhad','IRN',1887405),
+(1382,'Esfahan','IRN',1266072),
+(1383,'Tabriz','IRN',1191043),
+(1384,'Shiraz','IRN',1053025),
+(1385,'Karaj','IRN',940968),
+(1386,'Ahvaz','IRN',804980),
+(1387,'Qom','IRN',777677),
+(1388,'Kermanshah','IRN',692986),
+(1389,'Urmia','IRN',435200),
+(1390,'Zahedan','IRN',419518),
+(1391,'Rasht','IRN',417748),
+(1392,'Hamadan','IRN',401281),
+(1393,'Kerman','IRN',384991),
+(1394,'Arak','IRN',380755),
+(1395,'Ardebil','IRN',340386),
+(1396,'Yazd','IRN',326776),
+(1397,'Qazvin','IRN',291117),
+(1398,'Zanjan','IRN',286295),
+(1399,'Sanandaj','IRN',277808),
+(1400,'Bandar-e-Abbas','IRN',273578);
+INSERT INTO City VALUES
+(1401,'Khorramabad','IRN',272815),
+(1402,'Eslamshahr','IRN',265450),
+(1403,'Borujerd','IRN',217804),
+(1404,'Abadan','IRN',206073),
+(1405,'Dezful','IRN',202639),
+(1406,'Kashan','IRN',201372),
+(1407,'Sari','IRN',195882),
+(1408,'Gorgan','IRN',188710),
+(1409,'Najafabad','IRN',178498),
+(1410,'Sabzevar','IRN',170738),
+(1411,'Khomeynishahr','IRN',165888),
+(1412,'Amol','IRN',159092),
+(1413,'Neyshabur','IRN',158847),
+(1414,'Babol','IRN',158346),
+(1415,'Khoy','IRN',148944),
+(1416,'Malayer','IRN',144373),
+(1417,'Bushehr','IRN',143641),
+(1418,'Qaemshahr','IRN',143286),
+(1419,'Qarchak','IRN',142690),
+(1420,'Qods','IRN',138278),
+(1421,'Sirjan','IRN',135024),
+(1422,'Bojnurd','IRN',134835),
+(1423,'Maragheh','IRN',132318),
+(1424,'Birjand','IRN',127608),
+(1425,'Ilam','IRN',126346),
+(1426,'Bukan','IRN',120020),
+(1427,'Masjed-e-Soleyman','IRN',116883),
+(1428,'Saqqez','IRN',115394),
+(1429,'Gonbad-e Qabus','IRN',111253),
+(1430,'Saveh','IRN',111245),
+(1431,'Mahabad','IRN',107799),
+(1432,'Varamin','IRN',107233),
+(1433,'Andimeshk','IRN',106923),
+(1434,'Khorramshahr','IRN',105636),
+(1435,'Shahrud','IRN',104765),
+(1436,'Marv Dasht','IRN',103579),
+(1437,'Zabol','IRN',100887),
+(1438,'Shahr-e Kord','IRN',100477),
+(1439,'Bandar-e Anzali','IRN',98500),
+(1440,'Rafsanjan','IRN',98300),
+(1441,'Marand','IRN',96400),
+(1442,'Torbat-e Heydariyeh','IRN',94600),
+(1443,'Jahrom','IRN',94200),
+(1444,'Semnan','IRN',91045),
+(1445,'Miandoab','IRN',90100),
+(1446,'Qomsheh','IRN',89800),
+(1447,'Dublin','IRL',481854),
+(1448,'Cork','IRL',127187),
+(1449,'Reykjavík','ISL',109184),
+(1450,'Jerusalem','ISR',633700),
+(1451,'Tel Aviv-Jaffa','ISR',348100),
+(1452,'Haifa','ISR',265700),
+(1453,'Rishon Le Ziyyon','ISR',188200),
+(1454,'Beerseba','ISR',163700),
+(1455,'Holon','ISR',163100),
+(1456,'Petah Tiqwa','ISR',159400),
+(1457,'Ashdod','ISR',155800),
+(1458,'Netanya','ISR',154900),
+(1459,'Bat Yam','ISR',137000),
+(1460,'Bene Beraq','ISR',133900),
+(1461,'Ramat Gan','ISR',126900),
+(1462,'Ashqelon','ISR',92300),
+(1463,'Rehovot','ISR',90300),
+(1464,'Roma','ITA',2643581),
+(1465,'Milano','ITA',1300977),
+(1466,'Napoli','ITA',1002619),
+(1467,'Torino','ITA',903705),
+(1468,'Palermo','ITA',683794),
+(1469,'Genova','ITA',636104),
+(1470,'Bologna','ITA',381161),
+(1471,'Firenze','ITA',376662),
+(1472,'Catania','ITA',337862),
+(1473,'Bari','ITA',331848),
+(1474,'Venezia','ITA',277305),
+(1475,'Messina','ITA',259156),
+(1476,'Verona','ITA',255268),
+(1477,'Trieste','ITA',216459),
+(1478,'Padova','ITA',211391),
+(1479,'Taranto','ITA',208214),
+(1480,'Brescia','ITA',191317),
+(1481,'Reggio di Calabria','ITA',179617),
+(1482,'Modena','ITA',176022),
+(1483,'Prato','ITA',172473),
+(1484,'Parma','ITA',168717),
+(1485,'Cagliari','ITA',165926),
+(1486,'Livorno','ITA',161673),
+(1487,'Perugia','ITA',156673),
+(1488,'Foggia','ITA',154891),
+(1489,'Reggio nell´ Emilia','ITA',143664),
+(1490,'Salerno','ITA',142055),
+(1491,'Ravenna','ITA',138418),
+(1492,'Ferrara','ITA',132127),
+(1493,'Rimini','ITA',131062),
+(1494,'Syrakusa','ITA',126282),
+(1495,'Sassari','ITA',120803),
+(1496,'Monza','ITA',119516),
+(1497,'Bergamo','ITA',117837),
+(1498,'Pescara','ITA',115698),
+(1499,'Latina','ITA',114099),
+(1500,'Vicenza','ITA',109738),
+(1501,'Terni','ITA',107770),
+(1502,'Forlì','ITA',107475),
+(1503,'Trento','ITA',104906),
+(1504,'Novara','ITA',102037),
+(1505,'Piacenza','ITA',98384),
+(1506,'Ancona','ITA',98329),
+(1507,'Lecce','ITA',98208),
+(1508,'Bolzano','ITA',97232),
+(1509,'Catanzaro','ITA',96700),
+(1510,'La Spezia','ITA',95504),
+(1511,'Udine','ITA',94932),
+(1512,'Torre del Greco','ITA',94505),
+(1513,'Andria','ITA',94443),
+(1514,'Brindisi','ITA',93454),
+(1515,'Giugliano in Campania','ITA',93286),
+(1516,'Pisa','ITA',92379),
+(1517,'Barletta','ITA',91904),
+(1518,'Arezzo','ITA',91729),
+(1519,'Alessandria','ITA',90289),
+(1520,'Cesena','ITA',89852),
+(1521,'Pesaro','ITA',88987),
+(1522,'Dili','TMP',47900),
+(1523,'Wien','AUT',1608144),
+(1524,'Graz','AUT',240967),
+(1525,'Linz','AUT',188022),
+(1526,'Salzburg','AUT',144247),
+(1527,'Innsbruck','AUT',111752),
+(1528,'Klagenfurt','AUT',91141),
+(1529,'Spanish Town','JAM',110379),
+(1530,'Kingston','JAM',103962),
+(1531,'Portmore','JAM',99799),
+(1532,'Tokyo','JPN',7980230),
+(1533,'Jokohama [Yokohama]','JPN',3339594),
+(1534,'Osaka','JPN',2595674),
+(1535,'Nagoya','JPN',2154376),
+(1536,'Sapporo','JPN',1790886),
+(1537,'Kioto','JPN',1461974),
+(1538,'Kobe','JPN',1425139),
+(1539,'Fukuoka','JPN',1308379),
+(1540,'Kawasaki','JPN',1217359),
+(1541,'Hiroshima','JPN',1119117),
+(1542,'Kitakyushu','JPN',1016264),
+(1543,'Sendai','JPN',989975),
+(1544,'Chiba','JPN',863930),
+(1545,'Sakai','JPN',797735),
+(1546,'Kumamoto','JPN',656734),
+(1547,'Okayama','JPN',624269),
+(1548,'Sagamihara','JPN',586300),
+(1549,'Hamamatsu','JPN',568796),
+(1550,'Kagoshima','JPN',549977),
+(1551,'Funabashi','JPN',545299),
+(1552,'Higashiosaka','JPN',517785),
+(1553,'Hachioji','JPN',513451),
+(1554,'Niigata','JPN',497464),
+(1555,'Amagasaki','JPN',481434),
+(1556,'Himeji','JPN',475167),
+(1557,'Shizuoka','JPN',473854),
+(1558,'Urawa','JPN',469675),
+(1559,'Matsuyama','JPN',466133),
+(1560,'Matsudo','JPN',461126),
+(1561,'Kanazawa','JPN',455386),
+(1562,'Kawaguchi','JPN',452155),
+(1563,'Ichikawa','JPN',441893),
+(1564,'Omiya','JPN',441649),
+(1565,'Utsunomiya','JPN',440353),
+(1566,'Oita','JPN',433401),
+(1567,'Nagasaki','JPN',432759),
+(1568,'Yokosuka','JPN',430200),
+(1569,'Kurashiki','JPN',425103),
+(1570,'Gifu','JPN',408007),
+(1571,'Hirakata','JPN',403151),
+(1572,'Nishinomiya','JPN',397618),
+(1573,'Toyonaka','JPN',396689),
+(1574,'Wakayama','JPN',391233),
+(1575,'Fukuyama','JPN',376921),
+(1576,'Fujisawa','JPN',372840),
+(1577,'Asahikawa','JPN',364813),
+(1578,'Machida','JPN',364197),
+(1579,'Nara','JPN',362812),
+(1580,'Takatsuki','JPN',361747),
+(1581,'Iwaki','JPN',361737),
+(1582,'Nagano','JPN',361391),
+(1583,'Toyohashi','JPN',360066),
+(1584,'Toyota','JPN',346090),
+(1585,'Suita','JPN',345750),
+(1586,'Takamatsu','JPN',332471),
+(1587,'Koriyama','JPN',330335),
+(1588,'Okazaki','JPN',328711),
+(1589,'Kawagoe','JPN',327211),
+(1590,'Tokorozawa','JPN',325809),
+(1591,'Toyama','JPN',325790),
+(1592,'Kochi','JPN',324710),
+(1593,'Kashiwa','JPN',320296),
+(1594,'Akita','JPN',314440),
+(1595,'Miyazaki','JPN',303784),
+(1596,'Koshigaya','JPN',301446),
+(1597,'Naha','JPN',299851),
+(1598,'Aomori','JPN',295969),
+(1599,'Hakodate','JPN',294788),
+(1600,'Akashi','JPN',292253);
+INSERT INTO City VALUES
+(1601,'Yokkaichi','JPN',288173),
+(1602,'Fukushima','JPN',287525),
+(1603,'Morioka','JPN',287353),
+(1604,'Maebashi','JPN',284473),
+(1605,'Kasugai','JPN',282348),
+(1606,'Otsu','JPN',282070),
+(1607,'Ichihara','JPN',279280),
+(1608,'Yao','JPN',276421),
+(1609,'Ichinomiya','JPN',270828),
+(1610,'Tokushima','JPN',269649),
+(1611,'Kakogawa','JPN',266281),
+(1612,'Ibaraki','JPN',261020),
+(1613,'Neyagawa','JPN',257315),
+(1614,'Shimonoseki','JPN',257263),
+(1615,'Yamagata','JPN',255617),
+(1616,'Fukui','JPN',254818),
+(1617,'Hiratsuka','JPN',254207),
+(1618,'Mito','JPN',246559),
+(1619,'Sasebo','JPN',244240),
+(1620,'Hachinohe','JPN',242979),
+(1621,'Takasaki','JPN',239124),
+(1622,'Shimizu','JPN',239123),
+(1623,'Kurume','JPN',235611),
+(1624,'Fuji','JPN',231527),
+(1625,'Soka','JPN',222768),
+(1626,'Fuchu','JPN',220576),
+(1627,'Chigasaki','JPN',216015),
+(1628,'Atsugi','JPN',212407),
+(1629,'Numazu','JPN',211382),
+(1630,'Ageo','JPN',209442),
+(1631,'Yamato','JPN',208234),
+(1632,'Matsumoto','JPN',206801),
+(1633,'Kure','JPN',206504),
+(1634,'Takarazuka','JPN',205993),
+(1635,'Kasukabe','JPN',201838),
+(1636,'Chofu','JPN',201585),
+(1637,'Odawara','JPN',200171),
+(1638,'Kofu','JPN',199753),
+(1639,'Kushiro','JPN',197608),
+(1640,'Kishiwada','JPN',197276),
+(1641,'Hitachi','JPN',196622),
+(1642,'Nagaoka','JPN',192407),
+(1643,'Itami','JPN',190886),
+(1644,'Uji','JPN',188735),
+(1645,'Suzuka','JPN',184061),
+(1646,'Hirosaki','JPN',177522),
+(1647,'Ube','JPN',175206),
+(1648,'Kodaira','JPN',174984),
+(1649,'Takaoka','JPN',174380),
+(1650,'Obihiro','JPN',173685),
+(1651,'Tomakomai','JPN',171958),
+(1652,'Saga','JPN',170034),
+(1653,'Sakura','JPN',168072),
+(1654,'Kamakura','JPN',167661),
+(1655,'Mitaka','JPN',167268),
+(1656,'Izumi','JPN',166979),
+(1657,'Hino','JPN',166770),
+(1658,'Hadano','JPN',166512),
+(1659,'Ashikaga','JPN',165243),
+(1660,'Tsu','JPN',164543),
+(1661,'Sayama','JPN',162472),
+(1662,'Yachiyo','JPN',161222),
+(1663,'Tsukuba','JPN',160768),
+(1664,'Tachikawa','JPN',159430),
+(1665,'Kumagaya','JPN',157171),
+(1666,'Moriguchi','JPN',155941),
+(1667,'Otaru','JPN',155784),
+(1668,'Anjo','JPN',153823),
+(1669,'Narashino','JPN',152849),
+(1670,'Oyama','JPN',152820),
+(1671,'Ogaki','JPN',151758),
+(1672,'Matsue','JPN',149821),
+(1673,'Kawanishi','JPN',149794),
+(1674,'Hitachinaka','JPN',148006),
+(1675,'Niiza','JPN',147744),
+(1676,'Nagareyama','JPN',147738),
+(1677,'Tottori','JPN',147523),
+(1678,'Tama','JPN',146712),
+(1679,'Iruma','JPN',145922),
+(1680,'Ota','JPN',145317),
+(1681,'Omuta','JPN',142889),
+(1682,'Komaki','JPN',139827),
+(1683,'Ome','JPN',139216),
+(1684,'Kadoma','JPN',138953),
+(1685,'Yamaguchi','JPN',138210),
+(1686,'Higashimurayama','JPN',136970),
+(1687,'Yonago','JPN',136461),
+(1688,'Matsubara','JPN',135010),
+(1689,'Musashino','JPN',134426),
+(1690,'Tsuchiura','JPN',134072),
+(1691,'Joetsu','JPN',133505),
+(1692,'Miyakonojo','JPN',133183),
+(1693,'Misato','JPN',132957),
+(1694,'Kakamigahara','JPN',131831),
+(1695,'Daito','JPN',130594),
+(1696,'Seto','JPN',130470),
+(1697,'Kariya','JPN',127969),
+(1698,'Urayasu','JPN',127550),
+(1699,'Beppu','JPN',127486),
+(1700,'Niihama','JPN',127207),
+(1701,'Minoo','JPN',127026),
+(1702,'Fujieda','JPN',126897),
+(1703,'Abiko','JPN',126670),
+(1704,'Nobeoka','JPN',125547),
+(1705,'Tondabayashi','JPN',125094),
+(1706,'Ueda','JPN',124217),
+(1707,'Kashihara','JPN',124013),
+(1708,'Matsusaka','JPN',123582),
+(1709,'Isesaki','JPN',123285),
+(1710,'Zama','JPN',122046),
+(1711,'Kisarazu','JPN',121967),
+(1712,'Noda','JPN',121030),
+(1713,'Ishinomaki','JPN',120963),
+(1714,'Fujinomiya','JPN',119714),
+(1715,'Kawachinagano','JPN',119666),
+(1716,'Imabari','JPN',119357),
+(1717,'Aizuwakamatsu','JPN',119287),
+(1718,'Higashihiroshima','JPN',119166),
+(1719,'Habikino','JPN',118968),
+(1720,'Ebetsu','JPN',118805),
+(1721,'Hofu','JPN',118751),
+(1722,'Kiryu','JPN',118326),
+(1723,'Okinawa','JPN',117748),
+(1724,'Yaizu','JPN',117258),
+(1725,'Toyokawa','JPN',115781),
+(1726,'Ebina','JPN',115571),
+(1727,'Asaka','JPN',114815),
+(1728,'Higashikurume','JPN',111666),
+(1729,'Ikoma','JPN',111645),
+(1730,'Kitami','JPN',111295),
+(1731,'Koganei','JPN',110969),
+(1732,'Iwatsuki','JPN',110034),
+(1733,'Mishima','JPN',109699),
+(1734,'Handa','JPN',108600),
+(1735,'Muroran','JPN',108275),
+(1736,'Komatsu','JPN',107937),
+(1737,'Yatsushiro','JPN',107661),
+(1738,'Iida','JPN',107583),
+(1739,'Tokuyama','JPN',107078),
+(1740,'Kokubunji','JPN',106996),
+(1741,'Akishima','JPN',106914),
+(1742,'Iwakuni','JPN',106647),
+(1743,'Kusatsu','JPN',106232),
+(1744,'Kuwana','JPN',106121),
+(1745,'Sanda','JPN',105643),
+(1746,'Hikone','JPN',105508),
+(1747,'Toda','JPN',103969),
+(1748,'Tajimi','JPN',103171),
+(1749,'Ikeda','JPN',102710),
+(1750,'Fukaya','JPN',102156),
+(1751,'Ise','JPN',101732),
+(1752,'Sakata','JPN',101651),
+(1753,'Kasuga','JPN',101344),
+(1754,'Kamagaya','JPN',100821),
+(1755,'Tsuruoka','JPN',100713),
+(1756,'Hoya','JPN',100313),
+(1757,'Nishio','JPN',100032),
+(1758,'Tokai','JPN',99738),
+(1759,'Inazawa','JPN',98746),
+(1760,'Sakado','JPN',98221),
+(1761,'Isehara','JPN',98123),
+(1762,'Takasago','JPN',97632),
+(1763,'Fujimi','JPN',96972),
+(1764,'Urasoe','JPN',96002),
+(1765,'Yonezawa','JPN',95592),
+(1766,'Konan','JPN',95521),
+(1767,'Yamatokoriyama','JPN',95165),
+(1768,'Maizuru','JPN',94784),
+(1769,'Onomichi','JPN',93756),
+(1770,'Higashimatsuyama','JPN',93342),
+(1771,'Kimitsu','JPN',93216),
+(1772,'Isahaya','JPN',93058),
+(1773,'Kanuma','JPN',93053),
+(1774,'Izumisano','JPN',92583),
+(1775,'Kameoka','JPN',92398),
+(1776,'Mobara','JPN',91664),
+(1777,'Narita','JPN',91470),
+(1778,'Kashiwazaki','JPN',91229),
+(1779,'Tsuyama','JPN',91170),
+(1780,'Sanaa','YEM',503600),
+(1781,'Aden','YEM',398300),
+(1782,'Taizz','YEM',317600),
+(1783,'Hodeida','YEM',298500),
+(1784,'al-Mukalla','YEM',122400),
+(1785,'Ibb','YEM',103300),
+(1786,'Amman','JOR',1000000),
+(1787,'al-Zarqa','JOR',389815),
+(1788,'Irbid','JOR',231511),
+(1789,'al-Rusayfa','JOR',137247),
+(1790,'Wadi al-Sir','JOR',89104),
+(1791,'Flying Fish Cove','CXR',700),
+(1792,'Beograd','YUG',1204000),
+(1793,'Novi Sad','YUG',179626),
+(1794,'Niš','YUG',175391),
+(1795,'Priština','YUG',155496),
+(1796,'Kragujevac','YUG',147305),
+(1797,'Podgorica','YUG',135000),
+(1798,'Subotica','YUG',100386),
+(1799,'Prizren','YUG',92303),
+(1800,'Phnom Penh','KHM',570155);
+INSERT INTO City VALUES
+(1801,'Battambang','KHM',129800),
+(1802,'Siem Reap','KHM',105100),
+(1803,'Douala','CMR',1448300),
+(1804,'Yaoundé','CMR',1372800),
+(1805,'Garoua','CMR',177000),
+(1806,'Maroua','CMR',143000),
+(1807,'Bamenda','CMR',138000),
+(1808,'Bafoussam','CMR',131000),
+(1809,'Nkongsamba','CMR',112454),
+(1810,'Montréal','CAN',1016376),
+(1811,'Calgary','CAN',768082),
+(1812,'Toronto','CAN',688275),
+(1813,'North York','CAN',622632),
+(1814,'Winnipeg','CAN',618477),
+(1815,'Edmonton','CAN',616306),
+(1816,'Mississauga','CAN',608072),
+(1817,'Scarborough','CAN',594501),
+(1818,'Vancouver','CAN',514008),
+(1819,'Etobicoke','CAN',348845),
+(1820,'London','CAN',339917),
+(1821,'Hamilton','CAN',335614),
+(1822,'Ottawa','CAN',335277),
+(1823,'Laval','CAN',330393),
+(1824,'Surrey','CAN',304477),
+(1825,'Brampton','CAN',296711),
+(1826,'Windsor','CAN',207588),
+(1827,'Saskatoon','CAN',193647),
+(1828,'Kitchener','CAN',189959),
+(1829,'Markham','CAN',189098),
+(1830,'Regina','CAN',180400),
+(1831,'Burnaby','CAN',179209),
+(1832,'Québec','CAN',167264),
+(1833,'York','CAN',154980),
+(1834,'Richmond','CAN',148867),
+(1835,'Vaughan','CAN',147889),
+(1836,'Burlington','CAN',145150),
+(1837,'Oshawa','CAN',140173),
+(1838,'Oakville','CAN',139192),
+(1839,'Saint Catharines','CAN',136216),
+(1840,'Longueuil','CAN',127977),
+(1841,'Richmond Hill','CAN',116428),
+(1842,'Thunder Bay','CAN',115913),
+(1843,'Nepean','CAN',115100),
+(1844,'Cape Breton','CAN',114733),
+(1845,'East York','CAN',114034),
+(1846,'Halifax','CAN',113910),
+(1847,'Cambridge','CAN',109186),
+(1848,'Gloucester','CAN',107314),
+(1849,'Abbotsford','CAN',105403),
+(1850,'Guelph','CAN',103593),
+(1851,'Saint John´s','CAN',101936),
+(1852,'Coquitlam','CAN',101820),
+(1853,'Saanich','CAN',101388),
+(1854,'Gatineau','CAN',100702),
+(1855,'Delta','CAN',95411),
+(1856,'Sudbury','CAN',92686),
+(1857,'Kelowna','CAN',89442),
+(1858,'Barrie','CAN',89269),
+(1859,'Praia','CPV',94800),
+(1860,'Almaty','KAZ',1129400),
+(1861,'Qaraghandy','KAZ',436900),
+(1862,'Shymkent','KAZ',360100),
+(1863,'Taraz','KAZ',330100),
+(1864,'Astana','KAZ',311200),
+(1865,'Öskemen','KAZ',311000),
+(1866,'Pavlodar','KAZ',300500),
+(1867,'Semey','KAZ',269600),
+(1868,'Aqtöbe','KAZ',253100),
+(1869,'Qostanay','KAZ',221400),
+(1870,'Petropavl','KAZ',203500),
+(1871,'Oral','KAZ',195500),
+(1872,'Temirtau','KAZ',170500),
+(1873,'Qyzylorda','KAZ',157400),
+(1874,'Aqtau','KAZ',143400),
+(1875,'Atyrau','KAZ',142500),
+(1876,'Ekibastuz','KAZ',127200),
+(1877,'Kökshetau','KAZ',123400),
+(1878,'Rudnyy','KAZ',109500),
+(1879,'Taldyqorghan','KAZ',98000),
+(1880,'Zhezqazghan','KAZ',90000),
+(1881,'Nairobi','KEN',2290000),
+(1882,'Mombasa','KEN',461753),
+(1883,'Kisumu','KEN',192733),
+(1884,'Nakuru','KEN',163927),
+(1885,'Machakos','KEN',116293),
+(1886,'Eldoret','KEN',111882),
+(1887,'Meru','KEN',94947),
+(1888,'Nyeri','KEN',91258),
+(1889,'Bangui','CAF',524000),
+(1890,'Shanghai','CHN',9696300),
+(1891,'Peking','CHN',7472000),
+(1892,'Chongqing','CHN',6351600),
+(1893,'Tianjin','CHN',5286800),
+(1894,'Wuhan','CHN',4344600),
+(1895,'Harbin','CHN',4289800),
+(1896,'Shenyang','CHN',4265200),
+(1897,'Kanton [Guangzhou]','CHN',4256300),
+(1898,'Chengdu','CHN',3361500),
+(1899,'Nanking [Nanjing]','CHN',2870300),
+(1900,'Changchun','CHN',2812000),
+(1901,'Xi´an','CHN',2761400),
+(1902,'Dalian','CHN',2697000),
+(1903,'Qingdao','CHN',2596000),
+(1904,'Jinan','CHN',2278100),
+(1905,'Hangzhou','CHN',2190500),
+(1906,'Zhengzhou','CHN',2107200),
+(1907,'Shijiazhuang','CHN',2041500),
+(1908,'Taiyuan','CHN',1968400),
+(1909,'Kunming','CHN',1829500),
+(1910,'Changsha','CHN',1809800),
+(1911,'Nanchang','CHN',1691600),
+(1912,'Fuzhou','CHN',1593800),
+(1913,'Lanzhou','CHN',1565800),
+(1914,'Guiyang','CHN',1465200),
+(1915,'Ningbo','CHN',1371200),
+(1916,'Hefei','CHN',1369100),
+(1917,'Urumtši [Ürümqi]','CHN',1310100),
+(1918,'Anshan','CHN',1200000),
+(1919,'Fushun','CHN',1200000),
+(1920,'Nanning','CHN',1161800),
+(1921,'Zibo','CHN',1140000),
+(1922,'Qiqihar','CHN',1070000),
+(1923,'Jilin','CHN',1040000),
+(1924,'Tangshan','CHN',1040000),
+(1925,'Baotou','CHN',980000),
+(1926,'Shenzhen','CHN',950500),
+(1927,'Hohhot','CHN',916700),
+(1928,'Handan','CHN',840000),
+(1929,'Wuxi','CHN',830000),
+(1930,'Xuzhou','CHN',810000),
+(1931,'Datong','CHN',800000),
+(1932,'Yichun','CHN',800000),
+(1933,'Benxi','CHN',770000),
+(1934,'Luoyang','CHN',760000),
+(1935,'Suzhou','CHN',710000),
+(1936,'Xining','CHN',700200),
+(1937,'Huainan','CHN',700000),
+(1938,'Jixi','CHN',683885),
+(1939,'Daqing','CHN',660000),
+(1940,'Fuxin','CHN',640000),
+(1941,'Amoy [Xiamen]','CHN',627500),
+(1942,'Liuzhou','CHN',610000),
+(1943,'Shantou','CHN',580000),
+(1944,'Jinzhou','CHN',570000),
+(1945,'Mudanjiang','CHN',570000),
+(1946,'Yinchuan','CHN',544500),
+(1947,'Changzhou','CHN',530000),
+(1948,'Zhangjiakou','CHN',530000),
+(1949,'Dandong','CHN',520000),
+(1950,'Hegang','CHN',520000),
+(1951,'Kaifeng','CHN',510000),
+(1952,'Jiamusi','CHN',493409),
+(1953,'Liaoyang','CHN',492559),
+(1954,'Hengyang','CHN',487148),
+(1955,'Baoding','CHN',483155),
+(1956,'Hunjiang','CHN',482043),
+(1957,'Xinxiang','CHN',473762),
+(1958,'Huangshi','CHN',457601),
+(1959,'Haikou','CHN',454300),
+(1960,'Yantai','CHN',452127),
+(1961,'Bengbu','CHN',449245),
+(1962,'Xiangtan','CHN',441968),
+(1963,'Weifang','CHN',428522),
+ (1964,'Wuhu','CHN',425740),
+(1965,'Pingxiang','CHN',425579),
+(1966,'Yingkou','CHN',421589),
+(1967,'Anyang','CHN',420332),
+(1968,'Panzhihua','CHN',415466),
+(1969,'Pingdingshan','CHN',410775),
+(1970,'Xiangfan','CHN',410407),
+(1971,'Zhuzhou','CHN',409924),
+(1972,'Jiaozuo','CHN',409100),
+(1973,'Wenzhou','CHN',401871),
+(1974,'Zhangjiang','CHN',400997),
+(1975,'Zigong','CHN',393184),
+(1976,'Shuangyashan','CHN',386081),
+(1977,'Zaozhuang','CHN',380846),
+(1978,'Yakeshi','CHN',377869),
+(1979,'Yichang','CHN',371601),
+(1980,'Zhenjiang','CHN',368316),
+(1981,'Huaibei','CHN',366549),
+(1982,'Qinhuangdao','CHN',364972),
+(1983,'Guilin','CHN',364130),
+(1984,'Liupanshui','CHN',363954),
+(1985,'Panjin','CHN',362773),
+(1986,'Yangquan','CHN',362268),
+(1987,'Jinxi','CHN',357052),
+(1988,'Liaoyuan','CHN',354141),
+(1989,'Lianyungang','CHN',354139),
+(1990,'Xianyang','CHN',352125),
+(1991,'Tai´an','CHN',350696),
+(1992,'Chifeng','CHN',350077),
+(1993,'Shaoguan','CHN',350043),
+(1994,'Nantong','CHN',343341),
+(1995,'Leshan','CHN',341128),
+(1996,'Baoji','CHN',337765),
+(1997,'Linyi','CHN',324720),
+(1998,'Tonghua','CHN',324600),
+(1999,'Siping','CHN',317223),
+(2000,'Changzhi','CHN',317144);
+INSERT INTO City VALUES
+(2001,'Tengzhou','CHN',315083),
+(2002,'Chaozhou','CHN',313469),
+(2003,'Yangzhou','CHN',312892),
+(2004,'Dongwan','CHN',308669),
+(2005,'Ma´anshan','CHN',305421),
+(2006,'Foshan','CHN',303160),
+(2007,'Yueyang','CHN',302800),
+(2008,'Xingtai','CHN',302789),
+(2009,'Changde','CHN',301276),
+(2010,'Shihezi','CHN',299676),
+(2011,'Yancheng','CHN',296831),
+(2012,'Jiujiang','CHN',291187),
+(2013,'Dongying','CHN',281728),
+(2014,'Shashi','CHN',281352),
+(2015,'Xintai','CHN',281248),
+(2016,'Jingdezhen','CHN',281183),
+(2017,'Tongchuan','CHN',280657),
+(2018,'Zhongshan','CHN',278829),
+(2019,'Shiyan','CHN',273786),
+(2020,'Tieli','CHN',265683),
+(2021,'Jining','CHN',265248),
+(2022,'Wuhai','CHN',264081),
+(2023,'Mianyang','CHN',262947),
+(2024,'Luzhou','CHN',262892),
+(2025,'Zunyi','CHN',261862),
+(2026,'Shizuishan','CHN',257862),
+(2027,'Neijiang','CHN',256012),
+(2028,'Tongliao','CHN',255129),
+(2029,'Tieling','CHN',254842),
+(2030,'Wafangdian','CHN',251733),
+(2031,'Anqing','CHN',250718),
+(2032,'Shaoyang','CHN',247227),
+(2033,'Laiwu','CHN',246833),
+(2034,'Chengde','CHN',246799),
+(2035,'Tianshui','CHN',244974),
+(2036,'Nanyang','CHN',243303),
+(2037,'Cangzhou','CHN',242708),
+(2038,'Yibin','CHN',241019),
+(2039,'Huaiyin','CHN',239675),
+(2040,'Dunhua','CHN',235100),
+(2041,'Yanji','CHN',230892),
+(2042,'Jiangmen','CHN',230587),
+(2043,'Tongling','CHN',228017),
+(2044,'Suihua','CHN',227881),
+(2045,'Gongziling','CHN',226569),
+(2046,'Xiantao','CHN',222884),
+(2047,'Chaoyang','CHN',222394),
+(2048,'Ganzhou','CHN',220129),
+(2049,'Huzhou','CHN',218071),
+(2050,'Baicheng','CHN',217987),
+(2051,'Shangzi','CHN',215373),
+(2052,'Yangjiang','CHN',215196),
+(2053,'Qitaihe','CHN',214957),
+(2054,'Gejiu','CHN',214294),
+(2055,'Jiangyin','CHN',213659),
+(2056,'Hebi','CHN',212976),
+(2057,'Jiaxing','CHN',211526),
+(2058,'Wuzhou','CHN',210452),
+(2059,'Meihekou','CHN',209038),
+(2060,'Xuchang','CHN',208815),
+(2061,'Liaocheng','CHN',207844),
+(2062,'Haicheng','CHN',205560),
+(2063,'Qianjiang','CHN',205504),
+(2064,'Baiyin','CHN',204970),
+(2065,'Bei´an','CHN',204899),
+(2066,'Yixing','CHN',200824),
+(2067,'Laizhou','CHN',198664),
+(2068,'Qaramay','CHN',197602),
+(2069,'Acheng','CHN',197595),
+(2070,'Dezhou','CHN',195485),
+(2071,'Nanping','CHN',195064),
+(2072,'Zhaoqing','CHN',194784),
+(2073,'Beipiao','CHN',194301),
+(2074,'Fengcheng','CHN',193784),
+(2075,'Fuyu','CHN',192981),
+(2076,'Xinyang','CHN',192509),
+(2077,'Dongtai','CHN',192247),
+(2078,'Yuci','CHN',191356),
+(2079,'Honghu','CHN',190772),
+(2080,'Ezhou','CHN',190123),
+(2081,'Heze','CHN',189293),
+(2082,'Daxian','CHN',188101),
+(2083,'Linfen','CHN',187309),
+(2084,'Tianmen','CHN',186332),
+(2085,'Yiyang','CHN',185818),
+(2086,'Quanzhou','CHN',185154),
+(2087,'Rizhao','CHN',185048),
+(2088,'Deyang','CHN',182488),
+(2089,'Guangyuan','CHN',182241),
+(2090,'Changshu','CHN',181805),
+(2091,'Zhangzhou','CHN',181424),
+(2092,'Hailar','CHN',180650),
+(2093,'Nanchong','CHN',180273),
+(2094,'Jiutai','CHN',180130),
+(2095,'Zhaodong','CHN',179976),
+(2096,'Shaoxing','CHN',179818),
+(2097,'Fuyang','CHN',179572),
+(2098,'Maoming','CHN',178683),
+(2099,'Qujing','CHN',178669),
+(2100,'Ghulja','CHN',177193),
+(2101,'Jiaohe','CHN',176367),
+(2102,'Puyang','CHN',175988),
+(2103,'Huadian','CHN',175873),
+(2104,'Jiangyou','CHN',175753),
+(2105,'Qashqar','CHN',174570),
+(2106,'Anshun','CHN',174142),
+(2107,'Fuling','CHN',173878),
+(2108,'Xinyu','CHN',173524),
+(2109,'Hanzhong','CHN',169930),
+(2110,'Danyang','CHN',169603),
+(2111,'Chenzhou','CHN',169400),
+(2112,'Xiaogan','CHN',166280),
+(2113,'Shangqiu','CHN',164880),
+(2114,'Zhuhai','CHN',164747),
+(2115,'Qingyuan','CHN',164641),
+(2116,'Aqsu','CHN',164092),
+(2117,'Jining','CHN',163552),
+(2118,'Xiaoshan','CHN',162930),
+(2119,'Zaoyang','CHN',162198),
+(2120,'Xinghua','CHN',161910),
+(2121,'Hami','CHN',161315),
+(2122,'Huizhou','CHN',161023),
+(2123,'Jinmen','CHN',160794),
+(2124,'Sanming','CHN',160691),
+(2125,'Ulanhot','CHN',159538),
+(2126,'Korla','CHN',159344),
+(2127,'Wanxian','CHN',156823),
+(2128,'Rui´an','CHN',156468),
+(2129,'Zhoushan','CHN',156317),
+(2130,'Liangcheng','CHN',156307),
+(2131,'Jiaozhou','CHN',153364),
+(2132,'Taizhou','CHN',152442),
+(2133,'Suzhou','CHN',151862),
+(2134,'Yichun','CHN',151585),
+(2135,'Taonan','CHN',150168),
+(2136,'Pingdu','CHN',150123),
+(2137,'Ji´an','CHN',148583),
+(2138,'Longkou','CHN',148362),
+(2139,'Langfang','CHN',148105),
+(2140,'Zhoukou','CHN',146288),
+(2141,'Suining','CHN',146086),
+(2142,'Yulin','CHN',144467),
+(2143,'Jinhua','CHN',144280),
+(2144,'Liu´an','CHN',144248),
+(2145,'Shuangcheng','CHN',142659),
+(2146,'Suizhou','CHN',142302),
+(2147,'Ankang','CHN',142170),
+(2148,'Weinan','CHN',140169),
+(2149,'Longjing','CHN',139417),
+(2150,'Da´an','CHN',138963),
+(2151,'Lengshuijiang','CHN',137994),
+(2152,'Laiyang','CHN',137080),
+(2153,'Xianning','CHN',136811),
+(2154,'Dali','CHN',136554),
+(2155,'Anda','CHN',136446),
+(2156,'Jincheng','CHN',136396),
+(2157,'Longyan','CHN',134481),
+(2158,'Xichang','CHN',134419),
+(2159,'Wendeng','CHN',133910),
+(2160,'Hailun','CHN',133565),
+(2161,'Binzhou','CHN',133555),
+(2162,'Linhe','CHN',133183),
+(2163,'Wuwei','CHN',133101),
+(2164,'Duyun','CHN',132971),
+(2165,'Mishan','CHN',132744),
+(2166,'Shangrao','CHN',132455),
+(2167,'Changji','CHN',132260),
+(2168,'Meixian','CHN',132156),
+(2169,'Yushu','CHN',131861),
+(2170,'Tiefa','CHN',131807),
+(2171,'Huai´an','CHN',131149),
+(2172,'Leiyang','CHN',130115),
+(2173,'Zalantun','CHN',130031),
+(2174,'Weihai','CHN',128888),
+(2175,'Loudi','CHN',128418),
+(2176,'Qingzhou','CHN',128258),
+(2177,'Qidong','CHN',126872),
+(2178,'Huaihua','CHN',126785),
+(2179,'Luohe','CHN',126438),
+(2180,'Chuzhou','CHN',125341),
+(2181,'Kaiyuan','CHN',124219),
+(2182,'Linqing','CHN',123958),
+(2183,'Chaohu','CHN',123676),
+(2184,'Laohekou','CHN',123366),
+(2185,'Dujiangyan','CHN',123357),
+(2186,'Zhumadian','CHN',123232),
+(2187,'Linchuan','CHN',121949),
+(2188,'Jiaonan','CHN',121397),
+(2189,'Sanmenxia','CHN',120523),
+(2190,'Heyuan','CHN',120101),
+(2191,'Manzhouli','CHN',120023),
+(2192,'Lhasa','CHN',120000),
+(2193,'Lianyuan','CHN',118858),
+(2194,'Kuytun','CHN',118553),
+(2195,'Puqi','CHN',117264),
+(2196,'Hongjiang','CHN',116188),
+(2197,'Qinzhou','CHN',114586),
+(2198,'Renqiu','CHN',114256),
+(2199,'Yuyao','CHN',114065),
+(2200,'Guigang','CHN',114025);
+INSERT INTO City VALUES
+(2201,'Kaili','CHN',113958),
+(2202,'Yan´an','CHN',113277),
+(2203,'Beihai','CHN',112673),
+(2204,'Xuangzhou','CHN',112673),
+(2205,'Quzhou','CHN',112373),
+(2206,'Yong´an','CHN',111762),
+(2207,'Zixing','CHN',110048),
+(2208,'Liyang','CHN',109520),
+(2209,'Yizheng','CHN',109268),
+(2210,'Yumen','CHN',109234),
+(2211,'Liling','CHN',108504),
+(2212,'Yuncheng','CHN',108359),
+(2213,'Shanwei','CHN',107847),
+(2214,'Cixi','CHN',107329),
+(2215,'Yuanjiang','CHN',107004),
+(2216,'Bozhou','CHN',106346),
+(2217,'Jinchang','CHN',105287),
+(2218,'Fu´an','CHN',105265),
+(2219,'Suqian','CHN',105021),
+(2220,'Shishou','CHN',104571),
+(2221,'Hengshui','CHN',104269),
+(2222,'Danjiangkou','CHN',103211),
+(2223,'Fujin','CHN',103104),
+(2224,'Sanya','CHN',102820),
+(2225,'Guangshui','CHN',102770),
+(2226,'Huangshan','CHN',102628),
+(2227,'Xingcheng','CHN',102384),
+(2228,'Zhucheng','CHN',102134),
+(2229,'Kunshan','CHN',102052),
+(2230,'Haining','CHN',100478),
+(2231,'Pingliang','CHN',99265),
+(2232,'Fuqing','CHN',99193),
+(2233,'Xinzhou','CHN',98667),
+(2234,'Jieyang','CHN',98531),
+(2235,'Zhangjiagang','CHN',97994),
+(2236,'Tong Xian','CHN',97168),
+(2237,'Ya´an','CHN',95900),
+(2238,'Jinzhou','CHN',95761),
+(2239,'Emeishan','CHN',94000),
+(2240,'Enshi','CHN',93056),
+(2241,'Bose','CHN',93009),
+(2242,'Yuzhou','CHN',92889),
+(2243,'Kaiyuan','CHN',91999),
+(2244,'Tumen','CHN',91471),
+(2245,'Putian','CHN',91030),
+(2246,'Linhai','CHN',90870),
+(2247,'Xilin Hot','CHN',90646),
+(2248,'Shaowu','CHN',90286),
+(2249,'Junan','CHN',90222),
+(2250,'Huaying','CHN',89400),
+(2251,'Pingyi','CHN',89373),
+(2252,'Huangyan','CHN',89288),
+(2253,'Bishkek','KGZ',589400),
+(2254,'Osh','KGZ',222700),
+(2255,'Bikenibeu','KIR',5055),
+(2256,'Bairiki','KIR',2226),
+(2257,'Santafé de Bogotá','COL',6260862),
+(2258,'Cali','COL',2077386),
+(2259,'Medellín','COL',1861265),
+(2260,'Barranquilla','COL',1223260),
+(2261,'Cartagena','COL',805757),
+(2262,'Cúcuta','COL',606932),
+(2263,'Bucaramanga','COL',515555),
+(2264,'Ibagué','COL',393664),
+(2265,'Pereira','COL',381725),
+(2266,'Santa Marta','COL',359147),
+(2267,'Manizales','COL',337580),
+(2268,'Bello','COL',333470),
+(2269,'Pasto','COL',332396),
+(2270,'Neiva','COL',300052),
+(2271,'Soledad','COL',295058),
+(2272,'Armenia','COL',288977),
+(2273,'Villavicencio','COL',273140),
+(2274,'Soacha','COL',272058),
+(2275,'Valledupar','COL',263247),
+(2276,'Montería','COL',248245),
+(2277,'Itagüí','COL',228985),
+(2278,'Palmira','COL',226509),
+(2279,'Buenaventura','COL',224336),
+(2280,'Floridablanca','COL',221913),
+(2281,'Sincelejo','COL',220704),
+(2282,'Popayán','COL',200719),
+(2283,'Barrancabermeja','COL',178020),
+(2284,'Dos Quebradas','COL',159363),
+(2285,'Tuluá','COL',152488),
+(2286,'Envigado','COL',135848),
+(2287,'Cartago','COL',125884),
+(2288,'Girardot','COL',110963),
+(2289,'Buga','COL',110699),
+(2290,'Tunja','COL',109740),
+(2291,'Florencia','COL',108574),
+(2292,'Maicao','COL',108053),
+(2293,'Sogamoso','COL',107728),
+(2294,'Giron','COL',90688),
+(2295,'Moroni','COM',36000),
+(2296,'Brazzaville','COG',950000),
+(2297,'Pointe-Noire','COG',500000),
+(2298,'Kinshasa','COD',5064000),
+(2299,'Lubumbashi','COD',851381),
+(2300,'Mbuji-Mayi','COD',806475),
+(2301,'Kolwezi','COD',417810),
+(2302,'Kisangani','COD',417517),
+(2303,'Kananga','COD',393030),
+(2304,'Likasi','COD',299118),
+(2305,'Bukavu','COD',201569),
+(2306,'Kikwit','COD',182142),
+(2307,'Tshikapa','COD',180860),
+(2308,'Matadi','COD',172730),
+(2309,'Mbandaka','COD',169841),
+(2310,'Mwene-Ditu','COD',137459),
+(2311,'Boma','COD',135284),
+(2312,'Uvira','COD',115590),
+(2313,'Butembo','COD',109406),
+(2314,'Goma','COD',109094),
+(2315,'Kalemie','COD',101309),
+(2316,'Bantam','CCK',503),
+(2317,'West Island','CCK',167),
+(2318,'Pyongyang','PRK',2484000),
+(2319,'Hamhung','PRK',709730),
+(2320,'Chongjin','PRK',582480),
+(2321,'Nampo','PRK',566200),
+(2322,'Sinuiju','PRK',326011),
+(2323,'Wonsan','PRK',300148),
+(2324,'Phyongsong','PRK',272934),
+(2325,'Sariwon','PRK',254146),
+(2326,'Haeju','PRK',229172),
+(2327,'Kanggye','PRK',223410),
+(2328,'Kimchaek','PRK',179000),
+(2329,'Hyesan','PRK',178020),
+(2330,'Kaesong','PRK',171500),
+(2331,'Seoul','KOR',9981619),
+(2332,'Pusan','KOR',3804522),
+(2333,'Inchon','KOR',2559424),
+(2334,'Taegu','KOR',2548568),
+(2335,'Taejon','KOR',1425835),
+(2336,'Kwangju','KOR',1368341),
+(2337,'Ulsan','KOR',1084891),
+(2338,'Songnam','KOR',869094),
+(2339,'Puchon','KOR',779412),
+(2340,'Suwon','KOR',755550),
+(2341,'Anyang','KOR',591106),
+(2342,'Chonju','KOR',563153),
+(2343,'Chongju','KOR',531376),
+(2344,'Koyang','KOR',518282),
+(2345,'Ansan','KOR',510314),
+(2346,'Pohang','KOR',508899),
+(2347,'Chang-won','KOR',481694),
+(2348,'Masan','KOR',441242),
+(2349,'Kwangmyong','KOR',350914),
+(2350,'Chonan','KOR',330259),
+(2351,'Chinju','KOR',329886),
+(2352,'Iksan','KOR',322685),
+(2353,'Pyongtaek','KOR',312927),
+(2354,'Kumi','KOR',311431),
+(2355,'Uijongbu','KOR',276111),
+(2356,'Kyongju','KOR',272968),
+(2357,'Kunsan','KOR',266569),
+(2358,'Cheju','KOR',258511),
+(2359,'Kimhae','KOR',256370),
+(2360,'Sunchon','KOR',249263),
+(2361,'Mokpo','KOR',247452),
+(2362,'Yong-in','KOR',242643),
+(2363,'Wonju','KOR',237460),
+(2364,'Kunpo','KOR',235233),
+(2365,'Chunchon','KOR',234528),
+(2366,'Namyangju','KOR',229060),
+(2367,'Kangnung','KOR',220403),
+(2368,'Chungju','KOR',205206),
+(2369,'Andong','KOR',188443),
+(2370,'Yosu','KOR',183596),
+(2371,'Kyongsan','KOR',173746),
+(2372,'Paju','KOR',163379),
+(2373,'Yangsan','KOR',163351),
+(2374,'Ichon','KOR',155332),
+(2375,'Asan','KOR',154663),
+(2376,'Koje','KOR',147562),
+(2377,'Kimchon','KOR',147027),
+(2378,'Nonsan','KOR',146619),
+(2379,'Kuri','KOR',142173),
+(2380,'Chong-up','KOR',139111),
+(2381,'Chechon','KOR',137070),
+(2382,'Sosan','KOR',134746),
+(2383,'Shihung','KOR',133443),
+(2384,'Tong-yong','KOR',131717),
+(2385,'Kongju','KOR',131229),
+(2386,'Yongju','KOR',131097),
+(2387,'Chinhae','KOR',125997),
+(2388,'Sangju','KOR',124116),
+(2389,'Poryong','KOR',122604),
+(2390,'Kwang-yang','KOR',122052),
+(2391,'Miryang','KOR',121501),
+(2392,'Hanam','KOR',115812),
+(2393,'Kimje','KOR',115427),
+(2394,'Yongchon','KOR',113511),
+(2395,'Sachon','KOR',113494),
+(2396,'Uiwang','KOR',108788),
+(2397,'Naju','KOR',107831),
+(2398,'Namwon','KOR',103544),
+(2399,'Tonghae','KOR',95472),
+(2400,'Mun-gyong','KOR',92239);
+INSERT INTO City VALUES
+(2401,'Athenai','GRC',772072),
+(2402,'Thessaloniki','GRC',383967),
+(2403,'Pireus','GRC',182671),
+(2404,'Patras','GRC',153344),
+(2405,'Peristerion','GRC',137288),
+(2406,'Herakleion','GRC',116178),
+(2407,'Kallithea','GRC',114233),
+(2408,'Larisa','GRC',113090),
+(2409,'Zagreb','HRV',706770),
+(2410,'Split','HRV',189388),
+(2411,'Rijeka','HRV',167964),
+(2412,'Osijek','HRV',104761),
+(2413,'La Habana','CUB',2256000),
+(2414,'Santiago de Cuba','CUB',433180),
+(2415,'Camagüey','CUB',298726),
+(2416,'Holguín','CUB',249492),
+(2417,'Santa Clara','CUB',207350),
+(2418,'Guantánamo','CUB',205078),
+(2419,'Pinar del Río','CUB',142100),
+(2420,'Bayamo','CUB',141000),
+(2421,'Cienfuegos','CUB',132770),
+(2422,'Victoria de las Tunas','CUB',132350),
+(2423,'Matanzas','CUB',123273),
+(2424,'Manzanillo','CUB',109350),
+(2425,'Sancti-Spíritus','CUB',100751),
+(2426,'Ciego de Ãvila','CUB',98505),
+(2427,'al-Salimiya','KWT',130215),
+(2428,'Jalib al-Shuyukh','KWT',102178),
+(2429,'Kuwait','KWT',28859),
+(2430,'Nicosia','CYP',195000),
+(2431,'Limassol','CYP',154400),
+(2432,'Vientiane','LAO',531800),
+(2433,'Savannakhet','LAO',96652),
+(2434,'Riga','LVA',764328),
+(2435,'Daugavpils','LVA',114829),
+(2436,'Liepaja','LVA',89439),
+(2437,'Maseru','LSO',297000),
+(2438,'Beirut','LBN',1100000),
+(2439,'Tripoli','LBN',240000),
+(2440,'Monrovia','LBR',850000),
+(2441,'Tripoli','LBY',1682000),
+(2442,'Bengasi','LBY',804000),
+(2443,'Misrata','LBY',121669),
+(2444,'al-Zawiya','LBY',89338),
+(2445,'Schaan','LIE',5346),
+(2446,'Vaduz','LIE',5043),
+(2447,'Vilnius','LTU',577969),
+(2448,'Kaunas','LTU',412639),
+(2449,'Klaipeda','LTU',202451),
+(2450,'Šiauliai','LTU',146563),
+(2451,'Panevezys','LTU',133695),
+(2452,'Luxembourg [Luxemburg/Lëtzebuerg]','LUX',80700),
+(2453,'El-Aaiún','ESH',169000),
+(2454,'Macao','MAC',437500),
+(2455,'Antananarivo','MDG',675669),
+(2456,'Toamasina','MDG',127441),
+(2457,'Antsirabé','MDG',120239),
+(2458,'Mahajanga','MDG',100807),
+(2459,'Fianarantsoa','MDG',99005),
+(2460,'Skopje','MKD',444299),
+(2461,'Blantyre','MWI',478155),
+(2462,'Lilongwe','MWI',435964),
+(2463,'Male','MDV',71000),
+(2464,'Kuala Lumpur','MYS',1297526),
+(2465,'Ipoh','MYS',382853),
+(2466,'Johor Baharu','MYS',328436),
+(2467,'Petaling Jaya','MYS',254350),
+(2468,'Kelang','MYS',243355),
+(2469,'Kuala Terengganu','MYS',228119),
+(2470,'Pinang','MYS',219603),
+(2471,'Kota Bharu','MYS',219582),
+(2472,'Kuantan','MYS',199484),
+(2473,'Taiping','MYS',183261),
+(2474,'Seremban','MYS',182869),
+(2475,'Kuching','MYS',148059),
+(2476,'Sibu','MYS',126381),
+(2477,'Sandakan','MYS',125841),
+(2478,'Alor Setar','MYS',124412),
+(2479,'Selayang Baru','MYS',124228),
+(2480,'Sungai Petani','MYS',114763),
+(2481,'Shah Alam','MYS',102019),
+(2482,'Bamako','MLI',809552),
+(2483,'Birkirkara','MLT',21445),
+(2484,'Valletta','MLT',7073),
+(2485,'Casablanca','MAR',2940623),
+(2486,'Rabat','MAR',623457),
+(2487,'Marrakech','MAR',621914),
+(2488,'Fès','MAR',541162),
+(2489,'Tanger','MAR',521735),
+(2490,'Salé','MAR',504420),
+(2491,'Meknès','MAR',460000),
+(2492,'Oujda','MAR',365382),
+(2493,'Kénitra','MAR',292600),
+(2494,'Tétouan','MAR',277516),
+(2495,'Safi','MAR',262300),
+(2496,'Agadir','MAR',155244),
+(2497,'Mohammedia','MAR',154706),
+(2498,'Khouribga','MAR',152090),
+(2499,'Beni-Mellal','MAR',140212),
+(2500,'Témara','MAR',126303),
+(2501,'El Jadida','MAR',119083),
+(2502,'Nador','MAR',112450),
+(2503,'Ksar el Kebir','MAR',107065),
+(2504,'Settat','MAR',96200),
+(2505,'Taza','MAR',92700),
+(2506,'El Araich','MAR',90400),
+(2507,'Dalap-Uliga-Darrit','MHL',28000),
+(2508,'Fort-de-France','MTQ',94050),
+(2509,'Nouakchott','MRT',667300),
+(2510,'Nouâdhibou','MRT',97600),
+(2511,'Port-Louis','MUS',138200),
+(2512,'Beau Bassin-Rose Hill','MUS',100616),
+(2513,'Vacoas-Phoenix','MUS',98464),
+(2514,'Mamoutzou','MYT',12000),
+(2515,'Ciudad de México','MEX',8591309),
+(2516,'Guadalajara','MEX',1647720),
+(2517,'Ecatepec de Morelos','MEX',1620303),
+(2518,'Puebla','MEX',1346176),
+(2519,'Nezahualcóyotl','MEX',1224924),
+(2520,'Juárez','MEX',1217818),
+(2521,'Tijuana','MEX',1212232),
+(2522,'León','MEX',1133576),
+(2523,'Monterrey','MEX',1108499),
+(2524,'Zapopan','MEX',1002239),
+(2525,'Naucalpan de Juárez','MEX',857511),
+(2526,'Mexicali','MEX',764902),
+(2527,'Culiacán','MEX',744859),
+(2528,'Acapulco de Juárez','MEX',721011),
+(2529,'Tlalnepantla de Baz','MEX',720755),
+(2530,'Mérida','MEX',703324),
+(2531,'Chihuahua','MEX',670208),
+(2532,'San Luis Potosí','MEX',669353),
+(2533,'Guadalupe','MEX',668780),
+(2534,'Toluca','MEX',665617),
+(2535,'Aguascalientes','MEX',643360),
+(2536,'Querétaro','MEX',639839),
+(2537,'Morelia','MEX',619958),
+(2538,'Hermosillo','MEX',608697),
+(2539,'Saltillo','MEX',577352),
+(2540,'Torreón','MEX',529093),
+(2541,'Centro (Villahermosa)','MEX',519873),
+(2542,'San Nicolás de los Garza','MEX',495540),
+(2543,'Durango','MEX',490524),
+(2544,'Chimalhuacán','MEX',490245),
+(2545,'Tlaquepaque','MEX',475472),
+(2546,'Atizapán de Zaragoza','MEX',467262),
+(2547,'Veracruz','MEX',457119),
+(2548,'Cuautitlán Izcalli','MEX',452976),
+(2549,'Irapuato','MEX',440039),
+(2550,'Tuxtla Gutiérrez','MEX',433544),
+(2551,'Tultitlán','MEX',432411),
+(2552,'Reynosa','MEX',419776),
+(2553,'Benito Juárez','MEX',419276),
+(2554,'Matamoros','MEX',416428),
+(2555,'Xalapa','MEX',390058),
+(2556,'Celaya','MEX',382140),
+(2557,'Mazatlán','MEX',380265),
+(2558,'Ensenada','MEX',369573),
+(2559,'Ahome','MEX',358663),
+(2560,'Cajeme','MEX',355679),
+(2561,'Cuernavaca','MEX',337966),
+(2562,'Tonalá','MEX',336109),
+(2563,'Valle de Chalco Solidaridad','MEX',323113),
+(2564,'Nuevo Laredo','MEX',310277),
+(2565,'Tepic','MEX',305025),
+(2566,'Tampico','MEX',294789),
+(2567,'Ixtapaluca','MEX',293160),
+(2568,'Apodaca','MEX',282941),
+(2569,'Guasave','MEX',277201),
+(2570,'Gómez Palacio','MEX',272806),
+(2571,'Tapachula','MEX',271141),
+(2572,'Nicolás Romero','MEX',269393),
+(2573,'Coatzacoalcos','MEX',267037),
+(2574,'Uruapan','MEX',265211),
+(2575,'Victoria','MEX',262686),
+(2576,'Oaxaca de Juárez','MEX',256848),
+(2577,'Coacalco de Berriozábal','MEX',252270),
+(2578,'Pachuca de Soto','MEX',244688),
+(2579,'General Escobedo','MEX',232961),
+(2580,'Salamanca','MEX',226864),
+(2581,'Santa Catarina','MEX',226573),
+(2582,'Tehuacán','MEX',225943),
+(2583,'Chalco','MEX',222201),
+(2584,'Cárdenas','MEX',216903),
+(2585,'Campeche','MEX',216735),
+(2586,'La Paz','MEX',213045),
+(2587,'Othón P. Blanco (Chetumal)','MEX',208014),
+(2588,'Texcoco','MEX',203681),
+(2589,'La Paz','MEX',196708),
+(2590,'Metepec','MEX',194265),
+(2591,'Monclova','MEX',193657),
+(2592,'Huixquilucan','MEX',193156),
+(2593,'Chilpancingo de los Bravo','MEX',192509),
+(2594,'Puerto Vallarta','MEX',183741),
+(2595,'Fresnillo','MEX',182744),
+(2596,'Ciudad Madero','MEX',182012),
+(2597,'Soledad de Graciano Sánchez','MEX',179956),
+(2598,'San Juan del Río','MEX',179300),
+(2599,'San Felipe del Progreso','MEX',177330),
+(2600,'Córdoba','MEX',176952);
+INSERT INTO City VALUES
+(2601,'Tecámac','MEX',172410),
+(2602,'Ocosingo','MEX',171495),
+(2603,'Carmen','MEX',171367),
+(2604,'Lázaro Cárdenas','MEX',170878),
+(2605,'Jiutepec','MEX',170428),
+(2606,'Papantla','MEX',170123),
+(2607,'Comalcalco','MEX',164640),
+(2608,'Zamora','MEX',161191),
+(2609,'Nogales','MEX',159103),
+(2610,'Huimanguillo','MEX',158335),
+(2611,'Cuautla','MEX',153132),
+(2612,'Minatitlán','MEX',152983),
+(2613,'Poza Rica de Hidalgo','MEX',152678),
+(2614,'Ciudad Valles','MEX',146411),
+(2615,'Navolato','MEX',145396),
+(2616,'San Luis Río Colorado','MEX',145276),
+(2617,'Pénjamo','MEX',143927),
+(2618,'San Andrés Tuxtla','MEX',142251),
+(2619,'Guanajuato','MEX',141215),
+(2620,'Navojoa','MEX',140495),
+(2621,'Zitácuaro','MEX',137970),
+(2622,'Boca del Río','MEX',135721),
+(2623,'Allende','MEX',134645),
+(2624,'Silao','MEX',134037),
+(2625,'Macuspana','MEX',133795),
+(2626,'San Juan Bautista Tuxtepec','MEX',133675),
+(2627,'San Cristóbal de las Casas','MEX',132317),
+(2628,'Valle de Santiago','MEX',130557),
+(2629,'Guaymas','MEX',130108),
+(2630,'Colima','MEX',129454),
+(2631,'Dolores Hidalgo','MEX',128675),
+(2632,'Lagos de Moreno','MEX',127949),
+(2633,'Piedras Negras','MEX',127898),
+(2634,'Altamira','MEX',127490),
+(2635,'Túxpam','MEX',126475),
+(2636,'San Pedro Garza García','MEX',126147),
+(2637,'Cuauhtémoc','MEX',124279),
+(2638,'Manzanillo','MEX',124014),
+(2639,'Iguala de la Independencia','MEX',123883),
+(2640,'Zacatecas','MEX',123700),
+(2641,'Tlajomulco de Zúñiga','MEX',123220),
+(2642,'Tulancingo de Bravo','MEX',121946),
+(2643,'Zinacantepec','MEX',121715),
+(2644,'San Martín Texmelucan','MEX',121093),
+(2645,'Tepatitlán de Morelos','MEX',118948),
+(2646,'Martínez de la Torre','MEX',118815),
+(2647,'Orizaba','MEX',118488),
+(2648,'Apatzingán','MEX',117849),
+(2649,'Atlixco','MEX',117019),
+(2650,'Delicias','MEX',116132),
+(2651,'Ixtlahuaca','MEX',115548),
+(2652,'El Mante','MEX',112453),
+(2653,'Lerdo','MEX',112272),
+(2654,'Almoloya de Juárez','MEX',110550),
+(2655,'Acámbaro','MEX',110487),
+(2656,'Acuña','MEX',110388),
+(2657,'Guadalupe','MEX',108881),
+(2658,'Huejutla de Reyes','MEX',108017),
+(2659,'Hidalgo','MEX',106198),
+(2660,'Los Cabos','MEX',105199),
+(2661,'Comitán de Domínguez','MEX',104986),
+(2662,'Cunduacán','MEX',104164),
+(2663,'Río Bravo','MEX',103901),
+(2664,'Temapache','MEX',102824),
+(2665,'Chilapa de Alvarez','MEX',102716),
+(2666,'Hidalgo del Parral','MEX',100881),
+(2667,'San Francisco del Rincón','MEX',100149),
+(2668,'Taxco de Alarcón','MEX',99907),
+(2669,'Zumpango','MEX',99781),
+(2670,'San Pedro Cholula','MEX',99734),
+(2671,'Lerma','MEX',99714),
+(2672,'Tecomán','MEX',99296),
+(2673,'Las Margaritas','MEX',97389),
+(2674,'Cosoleacaque','MEX',97199),
+(2675,'San Luis de la Paz','MEX',96763),
+(2676,'José Azueta','MEX',95448),
+(2677,'Santiago Ixcuintla','MEX',95311),
+(2678,'San Felipe','MEX',95305),
+(2679,'Tejupilco','MEX',94934),
+(2680,'Tantoyuca','MEX',94709),
+(2681,'Salvatierra','MEX',94322),
+(2682,'Tultepec','MEX',93364),
+(2683,'Temixco','MEX',92686),
+(2684,'Matamoros','MEX',91858),
+(2685,'Pánuco','MEX',90551),
+(2686,'El Fuerte','MEX',89556),
+(2687,'Tierra Blanca','MEX',89143),
+(2688,'Weno','FSM',22000),
+(2689,'Palikir','FSM',8600),
+(2690,'Chisinau','MDA',719900),
+(2691,'Tiraspol','MDA',194300),
+(2692,'Balti','MDA',153400),
+(2693,'Bender (Tîghina)','MDA',125700),
+(2694,'Monte-Carlo','MCO',13154),
+(2695,'Monaco-Ville','MCO',1234),
+(2696,'Ulan Bator','MNG',773700),
+(2697,'Plymouth','MSR',2000),
+(2698,'Maputo','MOZ',1018938),
+(2699,'Matola','MOZ',424662),
+(2700,'Beira','MOZ',397368),
+(2701,'Nampula','MOZ',303346),
+(2702,'Chimoio','MOZ',171056),
+(2703,'Naçala-Porto','MOZ',158248),
+(2704,'Quelimane','MOZ',150116),
+(2705,'Mocuba','MOZ',124700),
+(2706,'Tete','MOZ',101984),
+(2707,'Xai-Xai','MOZ',99442),
+(2708,'Gurue','MOZ',99300),
+(2709,'Maxixe','MOZ',93985),
+(2710,'Rangoon (Yangon)','MMR',3361700),
+(2711,'Mandalay','MMR',885300),
+(2712,'Moulmein (Mawlamyine)','MMR',307900),
+(2713,'Pegu (Bago)','MMR',190900),
+(2714,'Bassein (Pathein)','MMR',183900),
+(2715,'Monywa','MMR',138600),
+(2716,'Sittwe (Akyab)','MMR',137600),
+(2717,'Taunggyi (Taunggye)','MMR',131500),
+(2718,'Meikhtila','MMR',129700),
+(2719,'Mergui (Myeik)','MMR',122700),
+(2720,'Lashio (Lasho)','MMR',107600),
+(2721,'Prome (Pyay)','MMR',105700),
+(2722,'Henzada (Hinthada)','MMR',104700),
+(2723,'Myingyan','MMR',103600),
+(2724,'Tavoy (Dawei)','MMR',96800),
+(2725,'Pagakku (Pakokku)','MMR',94800),
+(2726,'Windhoek','NAM',169000),
+(2727,'Yangor','NRU',4050),
+(2728,'Yaren','NRU',559),
+(2729,'Kathmandu','NPL',591835),
+(2730,'Biratnagar','NPL',157764),
+(2731,'Pokhara','NPL',146318),
+(2732,'Lalitapur','NPL',145847),
+(2733,'Birgunj','NPL',90639),
+(2734,'Managua','NIC',959000),
+(2735,'León','NIC',123865),
+(2736,'Chinandega','NIC',97387),
+(2737,'Masaya','NIC',88971),
+(2738,'Niamey','NER',420000),
+(2739,'Zinder','NER',120892),
+(2740,'Maradi','NER',112965),
+(2741,'Lagos','NGA',1518000),
+(2742,'Ibadan','NGA',1432000),
+(2743,'Ogbomosho','NGA',730000),
+(2744,'Kano','NGA',674100),
+(2745,'Oshogbo','NGA',476800),
+(2746,'Ilorin','NGA',475800),
+(2747,'Abeokuta','NGA',427400),
+(2748,'Port Harcourt','NGA',410000),
+(2749,'Zaria','NGA',379200),
+(2750,'Ilesha','NGA',378400),
+(2751,'Onitsha','NGA',371900),
+(2752,'Iwo','NGA',362000),
+(2753,'Ado-Ekiti','NGA',359400),
+(2754,'Abuja','NGA',350100),
+(2755,'Kaduna','NGA',342200),
+(2756,'Mushin','NGA',333200),
+(2757,'Maiduguri','NGA',320000),
+(2758,'Enugu','NGA',316100),
+(2759,'Ede','NGA',307100),
+(2760,'Aba','NGA',298900),
+(2761,'Ife','NGA',296800),
+(2762,'Ila','NGA',264000),
+(2763,'Oyo','NGA',256400),
+(2764,'Ikerre','NGA',244600),
+(2765,'Benin City','NGA',229400),
+(2766,'Iseyin','NGA',217300),
+(2767,'Katsina','NGA',206500),
+(2768,'Jos','NGA',206300),
+(2769,'Sokoto','NGA',204900),
+(2770,'Ilobu','NGA',199000),
+(2771,'Offa','NGA',197200),
+(2772,'Ikorodu','NGA',184900),
+(2773,'Ilawe-Ekiti','NGA',184500),
+(2774,'Owo','NGA',183500),
+(2775,'Ikirun','NGA',181400),
+(2776,'Shaki','NGA',174500),
+(2777,'Calabar','NGA',174400),
+(2778,'Ondo','NGA',173600),
+(2779,'Akure','NGA',162300),
+(2780,'Gusau','NGA',158000),
+(2781,'Ijebu-Ode','NGA',156400),
+(2782,'Effon-Alaiye','NGA',153100),
+(2783,'Kumo','NGA',148000),
+(2784,'Shomolu','NGA',147700),
+(2785,'Oka-Akoko','NGA',142900),
+(2786,'Ikare','NGA',140800),
+(2787,'Sapele','NGA',139200),
+(2788,'Deba Habe','NGA',138600),
+(2789,'Minna','NGA',136900),
+(2790,'Warri','NGA',126100),
+(2791,'Bida','NGA',125500),
+(2792,'Ikire','NGA',123300),
+(2793,'Makurdi','NGA',123100),
+(2794,'Lafia','NGA',122500),
+(2795,'Inisa','NGA',119800),
+(2796,'Shagamu','NGA',117200),
+(2797,'Awka','NGA',111200),
+(2798,'Gombe','NGA',107800),
+(2799,'Igboho','NGA',106800),
+(2800,'Ejigbo','NGA',105900);
+INSERT INTO City VALUES
+(2801,'Agege','NGA',105000),
+(2802,'Ise-Ekiti','NGA',103400),
+(2803,'Ugep','NGA',102600),
+(2804,'Epe','NGA',101000),
+(2805,'Alofi','NIU',682),
+(2806,'Kingston','NFK',800),
+(2807,'Oslo','NOR',508726),
+(2808,'Bergen','NOR',230948),
+(2809,'Trondheim','NOR',150166),
+(2810,'Stavanger','NOR',108848),
+(2811,'Bærum','NOR',101340),
+(2812,'Abidjan','CIV',2500000),
+(2813,'Bouaké','CIV',329850),
+(2814,'Yamoussoukro','CIV',130000),
+(2815,'Daloa','CIV',121842),
+(2816,'Korhogo','CIV',109445),
+(2817,'al-Sib','OMN',155000),
+(2818,'Salala','OMN',131813),
+(2819,'Bawshar','OMN',107500),
+(2820,'Suhar','OMN',90814),
+(2821,'Masqat','OMN',51969),
+(2822,'Karachi','PAK',9269265),
+(2823,'Lahore','PAK',5063499),
+(2824,'Faisalabad','PAK',1977246),
+(2825,'Rawalpindi','PAK',1406214),
+(2826,'Multan','PAK',1182441),
+(2827,'Hyderabad','PAK',1151274),
+(2828,'Gujranwala','PAK',1124749),
+(2829,'Peshawar','PAK',988005),
+(2830,'Quetta','PAK',560307),
+(2831,'Islamabad','PAK',524500),
+(2832,'Sargodha','PAK',455360),
+(2833,'Sialkot','PAK',417597),
+(2834,'Bahawalpur','PAK',403408),
+(2835,'Sukkur','PAK',329176),
+(2836,'Jhang','PAK',292214),
+(2837,'Sheikhupura','PAK',271875),
+(2838,'Larkana','PAK',270366),
+(2839,'Gujrat','PAK',250121),
+(2840,'Mardan','PAK',244511),
+(2841,'Kasur','PAK',241649),
+(2842,'Rahim Yar Khan','PAK',228479),
+(2843,'Sahiwal','PAK',207388),
+(2844,'Okara','PAK',200901),
+(2845,'Wah','PAK',198400),
+(2846,'Dera Ghazi Khan','PAK',188100),
+(2847,'Mirpur Khas','PAK',184500),
+(2848,'Nawabshah','PAK',183100),
+(2849,'Mingora','PAK',174500),
+(2850,'Chiniot','PAK',169300),
+(2851,'Kamoke','PAK',151000),
+(2852,'Mandi Burewala','PAK',149900),
+(2853,'Jhelum','PAK',145800),
+(2854,'Sadiqabad','PAK',141500),
+(2855,'Jacobabad','PAK',137700),
+(2856,'Shikarpur','PAK',133300),
+(2857,'Khanewal','PAK',133000),
+(2858,'Hafizabad','PAK',130200),
+(2859,'Kohat','PAK',125300),
+(2860,'Muzaffargarh','PAK',121600),
+(2861,'Khanpur','PAK',117800),
+(2862,'Gojra','PAK',115000),
+(2863,'Bahawalnagar','PAK',109600),
+(2864,'Muridke','PAK',108600),
+(2865,'Pak Pattan','PAK',107800),
+(2866,'Abottabad','PAK',106000),
+(2867,'Tando Adam','PAK',103400),
+(2868,'Jaranwala','PAK',103300),
+(2869,'Khairpur','PAK',102200),
+(2870,'Chishtian Mandi','PAK',101700),
+(2871,'Daska','PAK',101500),
+(2872,'Dadu','PAK',98600),
+(2873,'Mandi Bahauddin','PAK',97300),
+(2874,'Ahmadpur East','PAK',96000),
+(2875,'Kamalia','PAK',95300),
+(2876,'Khuzdar','PAK',93100),
+(2877,'Vihari','PAK',92300),
+(2878,'Dera Ismail Khan','PAK',90400),
+(2879,'Wazirabad','PAK',89700),
+(2880,'Nowshera','PAK',89400),
+(2881,'Koror','PLW',12000),
+(2882,'Ciudad de Panamá','PAN',471373),
+(2883,'San Miguelito','PAN',315382),
+(2884,'Port Moresby','PNG',247000),
+(2885,'Asunción','PRY',557776),
+(2886,'Ciudad del Este','PRY',133881),
+(2887,'San Lorenzo','PRY',133395),
+(2888,'Lambaré','PRY',99681),
+(2889,'Fernando de la Mora','PRY',95287),
+(2890,'Lima','PER',6464693),
+(2891,'Arequipa','PER',762000),
+(2892,'Trujillo','PER',652000),
+(2893,'Chiclayo','PER',517000),
+(2894,'Callao','PER',424294),
+(2895,'Iquitos','PER',367000),
+(2896,'Chimbote','PER',336000),
+(2897,'Huancayo','PER',327000),
+(2898,'Piura','PER',325000),
+(2899,'Cusco','PER',291000),
+(2900,'Pucallpa','PER',220866),
+(2901,'Tacna','PER',215683),
+(2902,'Ica','PER',194820),
+(2903,'Sullana','PER',147361),
+(2904,'Juliaca','PER',142576),
+(2905,'Huánuco','PER',129688),
+(2906,'Ayacucho','PER',118960),
+(2907,'Chincha Alta','PER',110016),
+(2908,'Cajamarca','PER',108009),
+(2909,'Puno','PER',101578),
+(2910,'Ventanilla','PER',101056),
+(2911,'Castilla','PER',90642),
+(2912,'Adamstown','PCN',42),
+(2913,'Garapan','MNP',9200),
+(2914,'Lisboa','PRT',563210),
+(2915,'Porto','PRT',273060),
+(2916,'Amadora','PRT',122106),
+(2917,'Coímbra','PRT',96100),
+(2918,'Braga','PRT',90535),
+(2919,'San Juan','PRI',434374),
+(2920,'Bayamón','PRI',224044),
+(2921,'Ponce','PRI',186475),
+(2922,'Carolina','PRI',186076),
+(2923,'Caguas','PRI',140502),
+(2924,'Arecibo','PRI',100131),
+(2925,'Guaynabo','PRI',100053),
+(2926,'Mayagüez','PRI',98434),
+(2927,'Toa Baja','PRI',94085),
+(2928,'Warszawa','POL',1615369),
+(2929,'Lódz','POL',800110),
+(2930,'Kraków','POL',738150),
+(2931,'Wroclaw','POL',636765),
+(2932,'Poznan','POL',576899),
+(2933,'Gdansk','POL',458988),
+(2934,'Szczecin','POL',416988),
+(2935,'Bydgoszcz','POL',386855),
+(2936,'Lublin','POL',356251),
+(2937,'Katowice','POL',345934),
+(2938,'Bialystok','POL',283937),
+(2939,'Czestochowa','POL',257812),
+(2940,'Gdynia','POL',253521),
+(2941,'Sosnowiec','POL',244102),
+(2942,'Radom','POL',232262),
+(2943,'Kielce','POL',212383),
+(2944,'Gliwice','POL',212164),
+(2945,'Torun','POL',206158),
+(2946,'Bytom','POL',205560),
+(2947,'Zabrze','POL',200177),
+(2948,'Bielsko-Biala','POL',180307),
+(2949,'Olsztyn','POL',170904),
+(2950,'Rzeszów','POL',162049),
+(2951,'Ruda Slaska','POL',159665),
+(2952,'Rybnik','POL',144582),
+(2953,'Walbrzych','POL',136923),
+(2954,'Tychy','POL',133178),
+(2955,'Dabrowa Górnicza','POL',131037),
+(2956,'Plock','POL',131011),
+(2957,'Elblag','POL',129782),
+(2958,'Opole','POL',129553),
+(2959,'Gorzów Wielkopolski','POL',126019),
+(2960,'Wloclawek','POL',123373),
+(2961,'Chorzów','POL',121708),
+(2962,'Tarnów','POL',121494),
+(2963,'Zielona Góra','POL',118182),
+(2964,'Koszalin','POL',112375),
+(2965,'Legnica','POL',109335),
+(2966,'Kalisz','POL',106641),
+(2967,'Grudziadz','POL',102434),
+(2968,'Slupsk','POL',102370),
+(2969,'Jastrzebie-Zdrój','POL',102294),
+(2970,'Jaworzno','POL',97929),
+(2971,'Jelenia Góra','POL',93901),
+(2972,'Malabo','GNQ',40000),
+(2973,'Doha','QAT',355000),
+(2974,'Paris','FRA',2125246),
+(2975,'Marseille','FRA',798430),
+(2976,'Lyon','FRA',445452),
+(2977,'Toulouse','FRA',390350),
+(2978,'Nice','FRA',342738),
+(2979,'Nantes','FRA',270251),
+(2980,'Strasbourg','FRA',264115),
+(2981,'Montpellier','FRA',225392),
+(2982,'Bordeaux','FRA',215363),
+(2983,'Rennes','FRA',206229),
+(2984,'Le Havre','FRA',190905),
+(2985,'Reims','FRA',187206),
+(2986,'Lille','FRA',184657),
+(2987,'St-Étienne','FRA',180210),
+(2988,'Toulon','FRA',160639),
+(2989,'Grenoble','FRA',153317),
+(2990,'Angers','FRA',151279),
+(2991,'Dijon','FRA',149867),
+(2992,'Brest','FRA',149634),
+(2993,'Le Mans','FRA',146105),
+(2994,'Clermont-Ferrand','FRA',137140),
+(2995,'Amiens','FRA',135501),
+(2996,'Aix-en-Provence','FRA',134222),
+(2997,'Limoges','FRA',133968),
+(2998,'Nîmes','FRA',133424),
+(2999,'Tours','FRA',132820),
+(3000,'Villeurbanne','FRA',124215);
+INSERT INTO City VALUES
+(3001,'Metz','FRA',123776),
+(3002,'Besançon','FRA',117733),
+(3003,'Caen','FRA',113987),
+(3004,'Orléans','FRA',113126),
+(3005,'Mulhouse','FRA',110359),
+(3006,'Rouen','FRA',106592),
+(3007,'Boulogne-Billancourt','FRA',106367),
+(3008,'Perpignan','FRA',105115),
+(3009,'Nancy','FRA',103605),
+(3010,'Roubaix','FRA',96984),
+(3011,'Argenteuil','FRA',93961),
+(3012,'Tourcoing','FRA',93540),
+(3013,'Montreuil','FRA',90674),
+(3014,'Cayenne','GUF',50699),
+(3015,'Faaa','PYF',25888),
+(3016,'Papeete','PYF',25553),
+(3017,'Saint-Denis','REU',131480),
+(3018,'Bucuresti','ROM',2016131),
+(3019,'Iasi','ROM',348070),
+(3020,'Constanta','ROM',342264),
+(3021,'Cluj-Napoca','ROM',332498),
+(3022,'Galati','ROM',330276),
+(3023,'Timisoara','ROM',324304),
+(3024,'Brasov','ROM',314225),
+(3025,'Craiova','ROM',313530),
+(3026,'Ploiesti','ROM',251348),
+(3027,'Braila','ROM',233756),
+(3028,'Oradea','ROM',222239),
+(3029,'Bacau','ROM',209235),
+(3030,'Pitesti','ROM',187170),
+(3031,'Arad','ROM',184408),
+(3032,'Sibiu','ROM',169611),
+(3033,'Târgu Mures','ROM',165153),
+(3034,'Baia Mare','ROM',149665),
+(3035,'Buzau','ROM',148372),
+(3036,'Satu Mare','ROM',130059),
+(3037,'Botosani','ROM',128730),
+(3038,'Piatra Neamt','ROM',125070),
+(3039,'Râmnicu Vâlcea','ROM',119741),
+(3040,'Suceava','ROM',118549),
+(3041,'Drobeta-Turnu Severin','ROM',117865),
+(3042,'Târgoviste','ROM',98980),
+(3043,'Focsani','ROM',98979),
+(3044,'Târgu Jiu','ROM',98524),
+(3045,'Tulcea','ROM',96278),
+(3046,'Resita','ROM',93976),
+(3047,'Kigali','RWA',286000),
+(3048,'Stockholm','SWE',750348),
+(3049,'Gothenburg [Göteborg]','SWE',466990),
+(3050,'Malmö','SWE',259579),
+(3051,'Uppsala','SWE',189569),
+(3052,'Linköping','SWE',133168),
+(3053,'Västerås','SWE',126328),
+(3054,'Örebro','SWE',124207),
+(3055,'Norrköping','SWE',122199),
+(3056,'Helsingborg','SWE',117737),
+(3057,'Jönköping','SWE',117095),
+(3058,'Umeå','SWE',104512),
+(3059,'Lund','SWE',98948),
+(3060,'Borås','SWE',96883),
+(3061,'Sundsvall','SWE',93126),
+(3062,'Gävle','SWE',90742),
+(3063,'Jamestown','SHN',1500),
+(3064,'Basseterre','KNA',11600),
+(3065,'Castries','LCA',2301),
+(3066,'Kingstown','VCT',17100),
+(3067,'Saint-Pierre','SPM',5808),
+(3068,'Berlin','DEU',3386667),
+(3069,'Hamburg','DEU',1704735),
+(3070,'Munich [München]','DEU',1194560),
+(3071,'Köln','DEU',962507),
+(3072,'Frankfurt am Main','DEU',643821),
+(3073,'Essen','DEU',599515),
+(3074,'Dortmund','DEU',590213),
+(3075,'Stuttgart','DEU',582443),
+(3076,'Düsseldorf','DEU',568855),
+(3077,'Bremen','DEU',540330),
+(3078,'Duisburg','DEU',519793),
+(3079,'Hannover','DEU',514718),
+(3080,'Leipzig','DEU',489532),
+(3081,'Nürnberg','DEU',486628),
+(3082,'Dresden','DEU',476668),
+(3083,'Bochum','DEU',392830),
+(3084,'Wuppertal','DEU',368993),
+(3085,'Bielefeld','DEU',321125),
+(3086,'Mannheim','DEU',307730),
+(3087,'Bonn','DEU',301048),
+(3088,'Gelsenkirchen','DEU',281979),
+(3089,'Karlsruhe','DEU',277204),
+(3090,'Wiesbaden','DEU',268716),
+(3091,'Münster','DEU',264670),
+(3092,'Mönchengladbach','DEU',263697),
+(3093,'Chemnitz','DEU',263222),
+(3094,'Augsburg','DEU',254867),
+(3095,'Halle/Saale','DEU',254360),
+(3096,'Braunschweig','DEU',246322),
+(3097,'Aachen','DEU',243825),
+(3098,'Krefeld','DEU',241769),
+(3099,'Magdeburg','DEU',235073),
+(3100,'Kiel','DEU',233795),
+(3101,'Oberhausen','DEU',222349),
+(3102,'Lübeck','DEU',213326),
+(3103,'Hagen','DEU',205201),
+(3104,'Rostock','DEU',203279),
+(3105,'Freiburg im Breisgau','DEU',202455),
+(3106,'Erfurt','DEU',201267),
+(3107,'Kassel','DEU',196211),
+(3108,'Saarbrücken','DEU',183836),
+(3109,'Mainz','DEU',183134),
+(3110,'Hamm','DEU',181804),
+(3111,'Herne','DEU',175661),
+(3112,'Mülheim an der Ruhr','DEU',173895),
+(3113,'Solingen','DEU',165583),
+(3114,'Osnabrück','DEU',164539),
+(3115,'Ludwigshafen am Rhein','DEU',163771),
+(3116,'Leverkusen','DEU',160841),
+(3117,'Oldenburg','DEU',154125),
+(3118,'Neuss','DEU',149702),
+(3119,'Heidelberg','DEU',139672),
+(3120,'Darmstadt','DEU',137776),
+(3121,'Paderborn','DEU',137647),
+(3122,'Potsdam','DEU',128983),
+(3123,'Würzburg','DEU',127350),
+(3124,'Regensburg','DEU',125236),
+(3125,'Recklinghausen','DEU',125022),
+(3126,'Göttingen','DEU',124775),
+(3127,'Bremerhaven','DEU',122735),
+(3128,'Wolfsburg','DEU',121954),
+(3129,'Bottrop','DEU',121097),
+(3130,'Remscheid','DEU',120125),
+(3131,'Heilbronn','DEU',119526),
+(3132,'Pforzheim','DEU',117227),
+(3133,'Offenbach am Main','DEU',116627),
+(3134,'Ulm','DEU',116103),
+(3135,'Ingolstadt','DEU',114826),
+(3136,'Gera','DEU',114718),
+(3137,'Salzgitter','DEU',112934),
+(3138,'Cottbus','DEU',110894),
+(3139,'Reutlingen','DEU',110343),
+(3140,'Fürth','DEU',109771),
+(3141,'Siegen','DEU',109225),
+(3142,'Koblenz','DEU',108003),
+(3143,'Moers','DEU',106837),
+(3144,'Bergisch Gladbach','DEU',106150),
+(3145,'Zwickau','DEU',104146),
+(3146,'Hildesheim','DEU',104013),
+(3147,'Witten','DEU',103384),
+(3148,'Schwerin','DEU',102878),
+(3149,'Erlangen','DEU',100750),
+(3150,'Kaiserslautern','DEU',100025),
+(3151,'Trier','DEU',99891),
+(3152,'Jena','DEU',99779),
+(3153,'Iserlohn','DEU',99474),
+(3154,'Gütersloh','DEU',95028),
+(3155,'Marl','DEU',93735),
+(3156,'Lünen','DEU',92044),
+(3157,'Düren','DEU',91092),
+(3158,'Ratingen','DEU',90951),
+(3159,'Velbert','DEU',89881),
+(3160,'Esslingen am Neckar','DEU',89667),
+(3161,'Honiara','SLB',50100),
+(3162,'Lusaka','ZMB',1317000),
+(3163,'Ndola','ZMB',329200),
+(3164,'Kitwe','ZMB',288600),
+(3165,'Kabwe','ZMB',154300),
+(3166,'Chingola','ZMB',142400),
+(3167,'Mufulira','ZMB',123900),
+(3168,'Luanshya','ZMB',118100),
+(3169,'Apia','WSM',35900),
+(3170,'Serravalle','SMR',4802),
+(3171,'San Marino','SMR',2294),
+(3172,'São Tomé','STP',49541),
+(3173,'Riyadh','SAU',3324000),
+(3174,'Jedda','SAU',2046300),
+(3175,'Mekka','SAU',965700),
+(3176,'Medina','SAU',608300),
+(3177,'al-Dammam','SAU',482300),
+(3178,'al-Taif','SAU',416100),
+(3179,'Tabuk','SAU',292600),
+(3180,'Burayda','SAU',248600),
+(3181,'al-Hufuf','SAU',225800),
+(3182,'al-Mubarraz','SAU',219100),
+(3183,'Khamis Mushayt','SAU',217900),
+(3184,'Hail','SAU',176800),
+(3185,'al-Kharj','SAU',152100),
+(3186,'al-Khubar','SAU',141700),
+(3187,'Jubayl','SAU',140800),
+(3188,'Hafar al-Batin','SAU',137800),
+(3189,'al-Tuqba','SAU',125700),
+(3190,'Yanbu','SAU',119800),
+(3191,'Abha','SAU',112300),
+(3192,'Ara´ar','SAU',108100),
+(3193,'al-Qatif','SAU',98900),
+(3194,'al-Hawiya','SAU',93900),
+(3195,'Unayza','SAU',91100),
+(3196,'Najran','SAU',91000),
+(3197,'Pikine','SEN',855287),
+(3198,'Dakar','SEN',785071),
+(3199,'Thiès','SEN',248000),
+(3200,'Kaolack','SEN',199000);
+INSERT INTO City VALUES
+(3201,'Ziguinchor','SEN',192000),
+(3202,'Rufisque','SEN',150000),
+(3203,'Saint-Louis','SEN',132400),
+(3204,'Mbour','SEN',109300),
+(3205,'Diourbel','SEN',99400),
+(3206,'Victoria','SYC',41000),
+(3207,'Freetown','SLE',850000),
+(3208,'Singapore','SGP',4017733),
+(3209,'Bratislava','SVK',448292),
+(3210,'Košice','SVK',241874),
+(3211,'Prešov','SVK',93977),
+(3212,'Ljubljana','SVN',270986),
+(3213,'Maribor','SVN',115532),
+(3214,'Mogadishu','SOM',997000),
+(3215,'Hargeysa','SOM',90000),
+(3216,'Kismaayo','SOM',90000),
+(3217,'Colombo','LKA',645000),
+(3218,'Dehiwala','LKA',203000),
+(3219,'Moratuwa','LKA',190000),
+(3220,'Jaffna','LKA',149000),
+(3221,'Kandy','LKA',140000),
+(3222,'Sri Jayawardenepura Kotte','LKA',118000),
+(3223,'Negombo','LKA',100000),
+(3224,'Omdurman','SDN',1271403),
+(3225,'Khartum','SDN',947483),
+(3226,'Sharq al-Nil','SDN',700887),
+(3227,'Port Sudan','SDN',308195),
+(3228,'Kassala','SDN',234622),
+(3229,'Obeid','SDN',229425),
+(3230,'Nyala','SDN',227183),
+(3231,'Wad Madani','SDN',211362),
+(3232,'al-Qadarif','SDN',191164),
+(3233,'Kusti','SDN',173599),
+(3234,'al-Fashir','SDN',141884),
+(3235,'Juba','SDN',114980),
+(3236,'Helsinki [Helsingfors]','FIN',555474),
+(3237,'Espoo','FIN',213271),
+(3238,'Tampere','FIN',195468),
+(3239,'Vantaa','FIN',178471),
+(3240,'Turku [Ã…bo]','FIN',172561),
+(3241,'Oulu','FIN',120753),
+(3242,'Lahti','FIN',96921),
+(3243,'Paramaribo','SUR',112000),
+(3244,'Mbabane','SWZ',61000),
+(3245,'Zürich','CHE',336800),
+(3246,'Geneve','CHE',173500),
+(3247,'Basel','CHE',166700),
+(3248,'Bern','CHE',122700),
+(3249,'Lausanne','CHE',114500),
+(3250,'Damascus','SYR',1347000),
+(3251,'Aleppo','SYR',1261983),
+(3252,'Hims','SYR',507404),
+(3253,'Hama','SYR',343361),
+(3254,'Latakia','SYR',264563),
+(3255,'al-Qamishliya','SYR',144286),
+(3256,'Dayr al-Zawr','SYR',140459),
+(3257,'Jaramana','SYR',138469),
+(3258,'Duma','SYR',131158),
+(3259,'al-Raqqa','SYR',108020),
+(3260,'Idlib','SYR',91081),
+(3261,'Dushanbe','TJK',524000),
+(3262,'Khujand','TJK',161500),
+(3263,'Taipei','TWN',2641312),
+(3264,'Kaohsiung','TWN',1475505),
+(3265,'Taichung','TWN',940589),
+(3266,'Tainan','TWN',728060),
+(3267,'Panchiao','TWN',523850),
+(3268,'Chungho','TWN',392176),
+(3269,'Keelung (Chilung)','TWN',385201),
+(3270,'Sanchung','TWN',380084),
+(3271,'Hsinchuang','TWN',365048),
+(3272,'Hsinchu','TWN',361958),
+(3273,'Chungli','TWN',318649),
+(3274,'Fengshan','TWN',318562),
+(3275,'Taoyuan','TWN',316438),
+(3276,'Chiayi','TWN',265109),
+(3277,'Hsintien','TWN',263603),
+(3278,'Changhwa','TWN',227715),
+(3279,'Yungho','TWN',227700),
+(3280,'Tucheng','TWN',224897),
+(3281,'Pingtung','TWN',214727),
+(3282,'Yungkang','TWN',193005),
+(3283,'Pingchen','TWN',188344),
+(3284,'Tali','TWN',171940),
+(3285,'Taiping','TWN',165524),
+(3286,'Pate','TWN',161700),
+(3287,'Fengyuan','TWN',161032),
+(3288,'Luchou','TWN',160516),
+(3289,'Hsichuh','TWN',154976),
+(3290,'Shulin','TWN',151260),
+(3291,'Yuanlin','TWN',126402),
+(3292,'Yangmei','TWN',126323),
+(3293,'Taliao','TWN',115897),
+(3294,'Kueishan','TWN',112195),
+(3295,'Tanshui','TWN',111882),
+(3296,'Taitung','TWN',111039),
+(3297,'Hualien','TWN',108407),
+(3298,'Nantou','TWN',104723),
+(3299,'Lungtan','TWN',103088),
+(3300,'Touliu','TWN',98900),
+(3301,'Tsaotun','TWN',96800),
+(3302,'Kangshan','TWN',92200),
+(3303,'Ilan','TWN',92000),
+(3304,'Miaoli','TWN',90000),
+(3305,'Dar es Salaam','TZA',1747000),
+(3306,'Dodoma','TZA',189000),
+(3307,'Mwanza','TZA',172300),
+(3308,'Zanzibar','TZA',157634),
+(3309,'Tanga','TZA',137400),
+(3310,'Mbeya','TZA',130800),
+(3311,'Morogoro','TZA',117800),
+(3312,'Arusha','TZA',102500),
+(3313,'Moshi','TZA',96800),
+(3314,'Tabora','TZA',92800),
+(3315,'København','DNK',495699),
+(3316,'Ã…rhus','DNK',284846),
+(3317,'Odense','DNK',183912),
+(3318,'Aalborg','DNK',161161),
+(3319,'Frederiksberg','DNK',90327),
+(3320,'Bangkok','THA',6320174),
+(3321,'Nonthaburi','THA',292100),
+(3322,'Nakhon Ratchasima','THA',181400),
+(3323,'Chiang Mai','THA',171100),
+(3324,'Udon Thani','THA',158100),
+(3325,'Hat Yai','THA',148632),
+(3326,'Khon Kaen','THA',126500),
+(3327,'Pak Kret','THA',126055),
+(3328,'Nakhon Sawan','THA',123800),
+(3329,'Ubon Ratchathani','THA',116300),
+(3330,'Songkhla','THA',94900),
+(3331,'Nakhon Pathom','THA',94100),
+(3332,'Lomé','TGO',375000),
+(3333,'Fakaofo','TKL',300),
+(3334,'Nuku´alofa','TON',22400),
+(3335,'Chaguanas','TTO',56601),
+(3336,'Port-of-Spain','TTO',43396),
+(3337,'N´Djaména','TCD',530965),
+(3338,'Moundou','TCD',99500),
+(3339,'Praha','CZE',1181126),
+(3340,'Brno','CZE',381862),
+(3341,'Ostrava','CZE',320041),
+(3342,'Plzen','CZE',166759),
+(3343,'Olomouc','CZE',102702),
+(3344,'Liberec','CZE',99155),
+(3345,'Ceské Budejovice','CZE',98186),
+(3346,'Hradec Králové','CZE',98080),
+(3347,'Ústí nad Labem','CZE',95491),
+(3348,'Pardubice','CZE',91309),
+(3349,'Tunis','TUN',690600),
+(3350,'Sfax','TUN',257800),
+(3351,'Ariana','TUN',197000),
+(3352,'Ettadhamen','TUN',178600),
+(3353,'Sousse','TUN',145900),
+(3354,'Kairouan','TUN',113100),
+(3355,'Biserta','TUN',108900),
+(3356,'Gabès','TUN',106600),
+(3357,'Istanbul','TUR',8787958),
+(3358,'Ankara','TUR',3038159),
+(3359,'Izmir','TUR',2130359),
+(3360,'Adana','TUR',1131198),
+(3361,'Bursa','TUR',1095842),
+(3362,'Gaziantep','TUR',789056),
+(3363,'Konya','TUR',628364),
+(3364,'Mersin (Içel)','TUR',587212),
+(3365,'Antalya','TUR',564914),
+(3366,'Diyarbakir','TUR',479884),
+(3367,'Kayseri','TUR',475657),
+(3368,'Eskisehir','TUR',470781),
+(3369,'Sanliurfa','TUR',405905),
+(3370,'Samsun','TUR',339871),
+(3371,'Malatya','TUR',330312),
+(3372,'Gebze','TUR',264170),
+(3373,'Denizli','TUR',253848),
+(3374,'Sivas','TUR',246642),
+(3375,'Erzurum','TUR',246535),
+(3376,'Tarsus','TUR',246206),
+(3377,'Kahramanmaras','TUR',245772),
+(3378,'Elâzig','TUR',228815),
+(3379,'Van','TUR',219319),
+(3380,'Sultanbeyli','TUR',211068),
+(3381,'Izmit (Kocaeli)','TUR',210068),
+(3382,'Manisa','TUR',207148),
+(3383,'Batman','TUR',203793),
+(3384,'Balikesir','TUR',196382),
+(3385,'Sakarya (Adapazari)','TUR',190641),
+(3386,'Iskenderun','TUR',153022),
+(3387,'Osmaniye','TUR',146003),
+(3388,'Çorum','TUR',145495),
+(3389,'Kütahya','TUR',144761),
+(3390,'Hatay (Antakya)','TUR',143982),
+(3391,'Kirikkale','TUR',142044),
+(3392,'Adiyaman','TUR',141529),
+(3393,'Trabzon','TUR',138234),
+(3394,'Ordu','TUR',133642),
+(3395,'Aydin','TUR',128651),
+(3396,'Usak','TUR',128162),
+(3397,'Edirne','TUR',123383),
+(3398,'Çorlu','TUR',123300),
+(3399,'Isparta','TUR',121911),
+(3400,'Karabük','TUR',118285);
+INSERT INTO City VALUES
+(3401,'Kilis','TUR',118245),
+(3402,'Alanya','TUR',117300),
+(3403,'Kiziltepe','TUR',112000),
+(3404,'Zonguldak','TUR',111542),
+(3405,'Siirt','TUR',107100),
+(3406,'Viransehir','TUR',106400),
+(3407,'Tekirdag','TUR',106077),
+(3408,'Karaman','TUR',104200),
+(3409,'Afyon','TUR',103984),
+(3410,'Aksaray','TUR',102681),
+(3411,'Ceyhan','TUR',102412),
+(3412,'Erzincan','TUR',102304),
+(3413,'Bismil','TUR',101400),
+(3414,'Nazilli','TUR',99900),
+(3415,'Tokat','TUR',99500),
+(3416,'Kars','TUR',93000),
+(3417,'Inegöl','TUR',90500),
+(3418,'Bandirma','TUR',90200),
+(3419,'Ashgabat','TKM',540600),
+(3420,'Chärjew','TKM',189200),
+(3421,'Dashhowuz','TKM',141800),
+(3422,'Mary','TKM',101000),
+(3423,'Cockburn Town','TCA',4800),
+(3424,'Funafuti','TUV',4600),
+(3425,'Kampala','UGA',890800),
+(3426,'Kyiv','UKR',2624000),
+(3427,'Harkova [Harkiv]','UKR',1500000),
+(3428,'Dnipropetrovsk','UKR',1103000),
+(3429,'Donetsk','UKR',1050000),
+(3430,'Odesa','UKR',1011000),
+(3431,'Zaporizzja','UKR',848000),
+(3432,'Lviv','UKR',788000),
+(3433,'Kryvyi Rig','UKR',703000),
+(3434,'Mykolajiv','UKR',508000),
+(3435,'Mariupol','UKR',490000),
+(3436,'Lugansk','UKR',469000),
+(3437,'Vinnytsja','UKR',391000),
+(3438,'Makijivka','UKR',384000),
+(3439,'Herson','UKR',353000),
+(3440,'Sevastopol','UKR',348000),
+(3441,'Simferopol','UKR',339000),
+(3442,'Pultava [Poltava]','UKR',313000),
+(3443,'Tšernigiv','UKR',313000),
+(3444,'Tšerkasy','UKR',309000),
+(3445,'Gorlivka','UKR',299000),
+(3446,'Zytomyr','UKR',297000),
+(3447,'Sumy','UKR',294000),
+(3448,'Dniprodzerzynsk','UKR',270000),
+(3449,'Kirovograd','UKR',265000),
+(3450,'Hmelnytskyi','UKR',262000),
+(3451,'Tšernivtsi','UKR',259000),
+(3452,'Rivne','UKR',245000),
+(3453,'Krementšuk','UKR',239000),
+(3454,'Ivano-Frankivsk','UKR',237000),
+(3455,'Ternopil','UKR',236000),
+(3456,'Lutsk','UKR',217000),
+(3457,'Bila Tserkva','UKR',215000),
+(3458,'Kramatorsk','UKR',186000),
+(3459,'Melitopol','UKR',169000),
+(3460,'Kertš','UKR',162000),
+(3461,'Nikopol','UKR',149000),
+(3462,'Berdjansk','UKR',130000),
+(3463,'Pavlograd','UKR',127000),
+(3464,'Sjeverodonetsk','UKR',127000),
+(3465,'Slovjansk','UKR',127000),
+(3466,'Uzgorod','UKR',127000),
+(3467,'Altševsk','UKR',119000),
+(3468,'Lysytšansk','UKR',116000),
+(3469,'Jevpatorija','UKR',112000),
+(3470,'Kamjanets-Podilskyi','UKR',109000),
+(3471,'Jenakijeve','UKR',105000),
+(3472,'Krasnyi Lutš','UKR',101000),
+(3473,'Stahanov','UKR',101000),
+(3474,'Oleksandrija','UKR',99000),
+(3475,'Konotop','UKR',96000),
+(3476,'Kostjantynivka','UKR',95000),
+(3477,'Berdytšiv','UKR',90000),
+(3478,'Izmajil','UKR',90000),
+(3479,'Šostka','UKR',90000),
+(3480,'Uman','UKR',90000),
+(3481,'Brovary','UKR',89000),
+(3482,'Mukatševe','UKR',89000),
+(3483,'Budapest','HUN',1811552),
+(3484,'Debrecen','HUN',203648),
+(3485,'Miskolc','HUN',172357),
+(3486,'Szeged','HUN',158158),
+(3487,'Pécs','HUN',157332),
+(3488,'Györ','HUN',127119),
+(3489,'Nyiregyháza','HUN',112419),
+(3490,'Kecskemét','HUN',105606),
+(3491,'Székesfehérvár','HUN',105119),
+(3492,'Montevideo','URY',1236000),
+(3493,'Nouméa','NCL',76293),
+(3494,'Auckland','NZL',381800),
+(3495,'Christchurch','NZL',324200),
+(3496,'Manukau','NZL',281800),
+(3497,'North Shore','NZL',187700),
+(3498,'Waitakere','NZL',170600),
+(3499,'Wellington','NZL',166700),
+(3500,'Dunedin','NZL',119600),
+(3501,'Hamilton','NZL',117100),
+(3502,'Lower Hutt','NZL',98100),
+(3503,'Toskent','UZB',2117500),
+(3504,'Namangan','UZB',370500),
+(3505,'Samarkand','UZB',361800),
+(3506,'Andijon','UZB',318600),
+(3507,'Buhoro','UZB',237100),
+(3508,'Karsi','UZB',194100),
+(3509,'Nukus','UZB',194100),
+(3510,'Kükon','UZB',190100),
+(3511,'Fargona','UZB',180500),
+(3512,'Circik','UZB',146400),
+(3513,'Margilon','UZB',140800),
+(3514,'Ãœrgenc','UZB',138900),
+(3515,'Angren','UZB',128000),
+(3516,'Cizah','UZB',124800),
+(3517,'Navoi','UZB',116300),
+(3518,'Olmalik','UZB',114900),
+(3519,'Termiz','UZB',109500),
+(3520,'Minsk','BLR',1674000),
+(3521,'Gomel','BLR',475000),
+(3522,'Mogiljov','BLR',356000),
+(3523,'Vitebsk','BLR',340000),
+(3524,'Grodno','BLR',302000),
+(3525,'Brest','BLR',286000),
+(3526,'Bobruisk','BLR',221000),
+(3527,'Baranovitši','BLR',167000),
+(3528,'Borisov','BLR',151000),
+(3529,'Pinsk','BLR',130000),
+(3530,'Orša','BLR',124000),
+(3531,'Mozyr','BLR',110000),
+(3532,'Novopolotsk','BLR',106000),
+(3533,'Lida','BLR',101000),
+(3534,'Soligorsk','BLR',101000),
+(3535,'Molodetšno','BLR',97000),
+(3536,'Mata-Utu','WLF',1137),
+(3537,'Port-Vila','VUT',33700),
+(3538,'Città del Vaticano','VAT',455),
+(3539,'Caracas','VEN',1975294),
+(3540,'Maracaíbo','VEN',1304776),
+(3541,'Barquisimeto','VEN',877239),
+(3542,'Valencia','VEN',794246),
+(3543,'Ciudad Guayana','VEN',663713),
+(3544,'Petare','VEN',488868),
+(3545,'Maracay','VEN',444443),
+(3546,'Barcelona','VEN',322267),
+(3547,'Maturín','VEN',319726),
+(3548,'San Cristóbal','VEN',319373),
+(3549,'Ciudad Bolívar','VEN',301107),
+(3550,'Cumaná','VEN',293105),
+(3551,'Mérida','VEN',224887),
+(3552,'Cabimas','VEN',221329),
+(3553,'Barinas','VEN',217831),
+(3554,'Turmero','VEN',217499),
+(3555,'Baruta','VEN',207290),
+(3556,'Puerto Cabello','VEN',187722),
+(3557,'Santa Ana de Coro','VEN',185766),
+(3558,'Los Teques','VEN',178784),
+(3559,'Punto Fijo','VEN',167215),
+(3560,'Guarenas','VEN',165889),
+(3561,'Acarigua','VEN',158954),
+(3562,'Puerto La Cruz','VEN',155700),
+(3563,'Ciudad Losada','VEN',134501),
+(3564,'Guacara','VEN',131334),
+(3565,'Valera','VEN',130281),
+(3566,'Guanare','VEN',125621),
+(3567,'Carúpano','VEN',119639),
+(3568,'Catia La Mar','VEN',117012),
+(3569,'El Tigre','VEN',116256),
+(3570,'Guatire','VEN',109121),
+(3571,'Calabozo','VEN',107146),
+(3572,'Pozuelos','VEN',105690),
+(3573,'Ciudad Ojeda','VEN',99354),
+(3574,'Ocumare del Tuy','VEN',97168),
+(3575,'Valle de la Pascua','VEN',95927),
+(3576,'Araure','VEN',94269),
+(3577,'San Fernando de Apure','VEN',93809),
+(3578,'San Felipe','VEN',90940),
+(3579,'El Limón','VEN',90000),
+(3580,'Moscow','RUS',8389200),
+(3581,'St Petersburg','RUS',4694000),
+(3582,'Novosibirsk','RUS',1398800),
+(3583,'Nizni Novgorod','RUS',1357000),
+(3584,'Jekaterinburg','RUS',1266300),
+(3585,'Samara','RUS',1156100),
+(3586,'Omsk','RUS',1148900),
+(3587,'Kazan','RUS',1101000),
+(3588,'Ufa','RUS',1091200),
+(3589,'Tšeljabinsk','RUS',1083200),
+(3590,'Rostov-na-Donu','RUS',1012700),
+(3591,'Perm','RUS',1009700),
+(3592,'Volgograd','RUS',993400),
+(3593,'Voronez','RUS',907700),
+(3594,'Krasnojarsk','RUS',875500),
+(3595,'Saratov','RUS',874000),
+(3596,'Toljatti','RUS',722900),
+(3597,'Uljanovsk','RUS',667400),
+(3598,'Izevsk','RUS',652800),
+(3599,'Krasnodar','RUS',639000),
+(3600,'Jaroslavl','RUS',616700);
+INSERT INTO City VALUES
+(3601,'Habarovsk','RUS',609400),
+(3602,'Vladivostok','RUS',606200),
+(3603,'Irkutsk','RUS',593700),
+(3604,'Barnaul','RUS',580100),
+(3605,'Novokuznetsk','RUS',561600),
+(3606,'Penza','RUS',532200),
+(3607,'Rjazan','RUS',529900),
+(3608,'Orenburg','RUS',523600),
+(3609,'Lipetsk','RUS',521000),
+(3610,'Nabereznyje Tšelny','RUS',514700),
+(3611,'Tula','RUS',506100),
+(3612,'Tjumen','RUS',503400),
+(3613,'Kemerovo','RUS',492700),
+(3614,'Astrahan','RUS',486100),
+(3615,'Tomsk','RUS',482100),
+(3616,'Kirov','RUS',466200),
+(3617,'Ivanovo','RUS',459200),
+(3618,'Tšeboksary','RUS',459200),
+(3619,'Brjansk','RUS',457400),
+(3620,'Tver','RUS',454900),
+(3621,'Kursk','RUS',443500),
+(3622,'Magnitogorsk','RUS',427900),
+(3623,'Kaliningrad','RUS',424400),
+(3624,'Nizni Tagil','RUS',390900),
+(3625,'Murmansk','RUS',376300),
+(3626,'Ulan-Ude','RUS',370400),
+(3627,'Kurgan','RUS',364700),
+(3628,'Arkangeli','RUS',361800),
+(3629,'Sotši','RUS',358600),
+(3630,'Smolensk','RUS',353400),
+(3631,'Orjol','RUS',344500),
+(3632,'Stavropol','RUS',343300),
+(3633,'Belgorod','RUS',342000),
+(3634,'Kaluga','RUS',339300),
+(3635,'Vladimir','RUS',337100),
+(3636,'Mahatškala','RUS',332800),
+(3637,'Tšerepovets','RUS',324400),
+(3638,'Saransk','RUS',314800),
+(3639,'Tambov','RUS',312000),
+(3640,'Vladikavkaz','RUS',310100),
+(3641,'Tšita','RUS',309900),
+(3642,'Vologda','RUS',302500),
+(3643,'Veliki Novgorod','RUS',299500),
+(3644,'Komsomolsk-na-Amure','RUS',291600),
+(3645,'Kostroma','RUS',288100),
+(3646,'Volzski','RUS',286900),
+(3647,'Taganrog','RUS',284400),
+(3648,'Petroskoi','RUS',282100),
+(3649,'Bratsk','RUS',277600),
+(3650,'Dzerzinsk','RUS',277100),
+(3651,'Surgut','RUS',274900),
+(3652,'Orsk','RUS',273900),
+(3653,'Sterlitamak','RUS',265200),
+(3654,'Angarsk','RUS',264700),
+(3655,'Joškar-Ola','RUS',249200),
+(3656,'Rybinsk','RUS',239600),
+(3657,'Prokopjevsk','RUS',237300),
+(3658,'Niznevartovsk','RUS',233900),
+(3659,'Naltšik','RUS',233400),
+(3660,'Syktyvkar','RUS',229700),
+(3661,'Severodvinsk','RUS',229300),
+(3662,'Bijsk','RUS',225000),
+(3663,'Niznekamsk','RUS',223400),
+(3664,'Blagoveštšensk','RUS',222000),
+(3665,'Šahty','RUS',221800),
+(3666,'Staryi Oskol','RUS',213800),
+(3667,'Zelenograd','RUS',207100),
+(3668,'Balakovo','RUS',206000),
+(3669,'Novorossijsk','RUS',203300),
+(3670,'Pihkova','RUS',201500),
+(3671,'Zlatoust','RUS',196900),
+(3672,'Jakutsk','RUS',195400),
+(3673,'Podolsk','RUS',194300),
+(3674,'Petropavlovsk-Kamtšatski','RUS',194100),
+(3675,'Kamensk-Uralski','RUS',190600),
+(3676,'Engels','RUS',189000),
+(3677,'Syzran','RUS',186900),
+(3678,'Grozny','RUS',186000),
+(3679,'Novotšerkassk','RUS',184400),
+(3680,'Berezniki','RUS',181900),
+(3681,'Juzno-Sahalinsk','RUS',179200),
+(3682,'Volgodonsk','RUS',178200),
+(3683,'Abakan','RUS',169200),
+(3684,'Maikop','RUS',167300),
+(3685,'Miass','RUS',166200),
+(3686,'Armavir','RUS',164900),
+(3687,'Ljubertsy','RUS',163900),
+(3688,'Rubtsovsk','RUS',162600),
+(3689,'Kovrov','RUS',159900),
+(3690,'Nahodka','RUS',157700),
+(3691,'Ussurijsk','RUS',157300),
+(3692,'Salavat','RUS',156800),
+(3693,'Mytištši','RUS',155700),
+(3694,'Kolomna','RUS',150700),
+(3695,'Elektrostal','RUS',147000),
+(3696,'Murom','RUS',142400),
+(3697,'Kolpino','RUS',141200),
+(3698,'Norilsk','RUS',140800),
+(3699,'Almetjevsk','RUS',140700),
+(3700,'Novomoskovsk','RUS',138100),
+(3701,'Dimitrovgrad','RUS',137000),
+(3702,'Pervouralsk','RUS',136100),
+(3703,'Himki','RUS',133700),
+(3704,'Balašiha','RUS',132900),
+(3705,'Nevinnomyssk','RUS',132600),
+(3706,'Pjatigorsk','RUS',132500),
+(3707,'Korolev','RUS',132400),
+(3708,'Serpuhov','RUS',132000),
+(3709,'Odintsovo','RUS',127400),
+(3710,'Orehovo-Zujevo','RUS',124900),
+(3711,'Kamyšin','RUS',124600),
+(3712,'Novotšeboksarsk','RUS',123400),
+(3713,'Tšerkessk','RUS',121700),
+(3714,'Atšinsk','RUS',121600),
+(3715,'Magadan','RUS',121000),
+(3716,'Mitšurinsk','RUS',120700),
+(3717,'Kislovodsk','RUS',120400),
+(3718,'Jelets','RUS',119400),
+(3719,'Seversk','RUS',118600),
+(3720,'Noginsk','RUS',117200),
+(3721,'Velikije Luki','RUS',116300),
+(3722,'Novokuibyševsk','RUS',116200),
+(3723,'Neftekamsk','RUS',115700),
+(3724,'Leninsk-Kuznetski','RUS',113800),
+(3725,'Oktjabrski','RUS',111500),
+(3726,'Sergijev Posad','RUS',111100),
+(3727,'Arzamas','RUS',110700),
+(3728,'Kiseljovsk','RUS',110000),
+(3729,'Novotroitsk','RUS',109600),
+(3730,'Obninsk','RUS',108300),
+(3731,'Kansk','RUS',107400),
+(3732,'Glazov','RUS',106300),
+(3733,'Solikamsk','RUS',106000),
+(3734,'Sarapul','RUS',105700),
+(3735,'Ust-Ilimsk','RUS',105200),
+(3736,'Štšolkovo','RUS',104900),
+(3737,'Mezduretšensk','RUS',104400),
+(3738,'Usolje-Sibirskoje','RUS',103500),
+(3739,'Elista','RUS',103300),
+(3740,'Novošahtinsk','RUS',101900),
+(3741,'Votkinsk','RUS',101700),
+(3742,'Kyzyl','RUS',101100),
+(3743,'Serov','RUS',100400),
+(3744,'Zelenodolsk','RUS',100200),
+(3745,'Zeleznodoroznyi','RUS',100100),
+(3746,'Kinešma','RUS',100000),
+(3747,'Kuznetsk','RUS',98200),
+(3748,'Uhta','RUS',98000),
+(3749,'Jessentuki','RUS',97900),
+(3750,'Tobolsk','RUS',97600),
+(3751,'Neftejugansk','RUS',97400),
+(3752,'Bataisk','RUS',97300),
+(3753,'Nojabrsk','RUS',97300),
+(3754,'Balašov','RUS',97100),
+(3755,'Zeleznogorsk','RUS',96900),
+(3756,'Zukovski','RUS',96500),
+(3757,'Anzero-Sudzensk','RUS',96100),
+(3758,'Bugulma','RUS',94100),
+(3759,'Zeleznogorsk','RUS',94000),
+(3760,'Novouralsk','RUS',93300),
+(3761,'Puškin','RUS',92900),
+(3762,'Vorkuta','RUS',92600),
+(3763,'Derbent','RUS',92300),
+(3764,'Kirovo-Tšepetsk','RUS',91600),
+(3765,'Krasnogorsk','RUS',91000),
+(3766,'Klin','RUS',90000),
+(3767,'Tšaikovski','RUS',90000),
+(3768,'Novyi Urengoi','RUS',89800),
+(3769,'Ho Chi Minh City','VNM',3980000),
+(3770,'Hanoi','VNM',1410000),
+(3771,'Haiphong','VNM',783133),
+(3772,'Da Nang','VNM',382674),
+(3773,'Biên Hoa','VNM',282095),
+(3774,'Nha Trang','VNM',221331),
+(3775,'Hue','VNM',219149),
+(3776,'Can Tho','VNM',215587),
+(3777,'Cam Pha','VNM',209086),
+(3778,'Nam Dinh','VNM',171699),
+(3779,'Quy Nhon','VNM',163385),
+(3780,'Vung Tau','VNM',145145),
+(3781,'Rach Gia','VNM',141132),
+(3782,'Long Xuyen','VNM',132681),
+(3783,'Thai Nguyen','VNM',127643),
+(3784,'Hong Gai','VNM',127484),
+(3785,'Phan Thiêt','VNM',114236),
+(3786,'Cam Ranh','VNM',114041),
+(3787,'Vinh','VNM',112455),
+(3788,'My Tho','VNM',108404),
+(3789,'Da Lat','VNM',106409),
+(3790,'Buon Ma Thuot','VNM',97044),
+(3791,'Tallinn','EST',403981),
+(3792,'Tartu','EST',101246),
+(3793,'New York','USA',8008278),
+(3794,'Los Angeles','USA',3694820),
+(3795,'Chicago','USA',2896016),
+(3796,'Houston','USA',1953631),
+(3797,'Philadelphia','USA',1517550),
+(3798,'Phoenix','USA',1321045),
+(3799,'San Diego','USA',1223400),
+(3800,'Dallas','USA',1188580);
+INSERT INTO City VALUES
+(3801,'San Antonio','USA',1144646),
+(3802,'Detroit','USA',951270),
+(3803,'San Jose','USA',894943),
+(3804,'Indianapolis','USA',791926),
+(3805,'San Francisco','USA',776733),
+(3806,'Jacksonville','USA',735167),
+(3807,'Columbus','USA',711470),
+(3808,'Austin','USA',656562),
+(3809,'Baltimore','USA',651154),
+(3810,'Memphis','USA',650100),
+(3811,'Milwaukee','USA',596974),
+(3812,'Boston','USA',589141),
+(3813,'Washington','USA',572059),
+(3814,'Nashville-Davidson','USA',569891),
+(3815,'El Paso','USA',563662),
+(3816,'Seattle','USA',563374),
+(3817,'Denver','USA',554636),
+(3818,'Charlotte','USA',540828),
+(3819,'Fort Worth','USA',534694),
+(3820,'Portland','USA',529121),
+(3821,'Oklahoma City','USA',506132),
+(3822,'Tucson','USA',486699),
+(3823,'New Orleans','USA',484674),
+(3824,'Las Vegas','USA',478434),
+(3825,'Cleveland','USA',478403),
+(3826,'Long Beach','USA',461522),
+(3827,'Albuquerque','USA',448607),
+(3828,'Kansas City','USA',441545),
+(3829,'Fresno','USA',427652),
+(3830,'Virginia Beach','USA',425257),
+(3831,'Atlanta','USA',416474),
+(3832,'Sacramento','USA',407018),
+(3833,'Oakland','USA',399484),
+(3834,'Mesa','USA',396375),
+(3835,'Tulsa','USA',393049),
+(3836,'Omaha','USA',390007),
+(3837,'Minneapolis','USA',382618),
+(3838,'Honolulu','USA',371657),
+(3839,'Miami','USA',362470),
+(3840,'Colorado Springs','USA',360890),
+(3841,'Saint Louis','USA',348189),
+(3842,'Wichita','USA',344284),
+(3843,'Santa Ana','USA',337977),
+(3844,'Pittsburgh','USA',334563),
+(3845,'Arlington','USA',332969),
+(3846,'Cincinnati','USA',331285),
+(3847,'Anaheim','USA',328014),
+(3848,'Toledo','USA',313619),
+(3849,'Tampa','USA',303447),
+(3850,'Buffalo','USA',292648),
+(3851,'Saint Paul','USA',287151),
+(3852,'Corpus Christi','USA',277454),
+(3853,'Aurora','USA',276393),
+(3854,'Raleigh','USA',276093),
+(3855,'Newark','USA',273546),
+(3856,'Lexington-Fayette','USA',260512),
+(3857,'Anchorage','USA',260283),
+(3858,'Louisville','USA',256231),
+(3859,'Riverside','USA',255166),
+(3860,'Saint Petersburg','USA',248232),
+(3861,'Bakersfield','USA',247057),
+(3862,'Stockton','USA',243771),
+(3863,'Birmingham','USA',242820),
+(3864,'Jersey City','USA',240055),
+(3865,'Norfolk','USA',234403),
+(3866,'Baton Rouge','USA',227818),
+(3867,'Hialeah','USA',226419),
+(3868,'Lincoln','USA',225581),
+(3869,'Greensboro','USA',223891),
+(3870,'Plano','USA',222030),
+(3871,'Rochester','USA',219773),
+(3872,'Glendale','USA',218812),
+(3873,'Akron','USA',217074),
+(3874,'Garland','USA',215768),
+(3875,'Madison','USA',208054),
+(3876,'Fort Wayne','USA',205727),
+(3877,'Fremont','USA',203413),
+(3878,'Scottsdale','USA',202705),
+(3879,'Montgomery','USA',201568),
+(3880,'Shreveport','USA',200145),
+(3881,'Augusta-Richmond County','USA',199775),
+(3882,'Lubbock','USA',199564),
+(3883,'Chesapeake','USA',199184),
+(3884,'Mobile','USA',198915),
+(3885,'Des Moines','USA',198682),
+(3886,'Grand Rapids','USA',197800),
+(3887,'Richmond','USA',197790),
+(3888,'Yonkers','USA',196086),
+(3889,'Spokane','USA',195629),
+(3890,'Glendale','USA',194973),
+(3891,'Tacoma','USA',193556),
+(3892,'Irving','USA',191615),
+(3893,'Huntington Beach','USA',189594),
+(3894,'Modesto','USA',188856),
+(3895,'Durham','USA',187035),
+(3896,'Columbus','USA',186291),
+(3897,'Orlando','USA',185951),
+(3898,'Boise City','USA',185787),
+(3899,'Winston-Salem','USA',185776),
+(3900,'San Bernardino','USA',185401),
+(3901,'Jackson','USA',184256),
+(3902,'Little Rock','USA',183133),
+(3903,'Salt Lake City','USA',181743),
+(3904,'Reno','USA',180480),
+(3905,'Newport News','USA',180150),
+(3906,'Chandler','USA',176581),
+(3907,'Laredo','USA',176576),
+(3908,'Henderson','USA',175381),
+(3909,'Arlington','USA',174838),
+(3910,'Knoxville','USA',173890),
+(3911,'Amarillo','USA',173627),
+(3912,'Providence','USA',173618),
+(3913,'Chula Vista','USA',173556),
+(3914,'Worcester','USA',172648),
+(3915,'Oxnard','USA',170358),
+(3916,'Dayton','USA',166179),
+(3917,'Garden Grove','USA',165196),
+(3918,'Oceanside','USA',161029),
+(3919,'Tempe','USA',158625),
+(3920,'Huntsville','USA',158216),
+(3921,'Ontario','USA',158007),
+(3922,'Chattanooga','USA',155554),
+(3923,'Fort Lauderdale','USA',152397),
+(3924,'Springfield','USA',152082),
+(3925,'Springfield','USA',151580),
+(3926,'Santa Clarita','USA',151088),
+(3927,'Salinas','USA',151060),
+(3928,'Tallahassee','USA',150624),
+(3929,'Rockford','USA',150115),
+(3930,'Pomona','USA',149473),
+(3931,'Metairie','USA',149428),
+(3932,'Paterson','USA',149222),
+(3933,'Overland Park','USA',149080),
+(3934,'Santa Rosa','USA',147595),
+(3935,'Syracuse','USA',147306),
+(3936,'Kansas City','USA',146866),
+(3937,'Hampton','USA',146437),
+(3938,'Lakewood','USA',144126),
+(3939,'Vancouver','USA',143560),
+(3940,'Irvine','USA',143072),
+(3941,'Aurora','USA',142990),
+(3942,'Moreno Valley','USA',142381),
+(3943,'Pasadena','USA',141674),
+(3944,'Hayward','USA',140030),
+(3945,'Brownsville','USA',139722),
+(3946,'Bridgeport','USA',139529),
+(3947,'Hollywood','USA',139357),
+(3948,'Warren','USA',138247),
+(3949,'Torrance','USA',137946),
+(3950,'Eugene','USA',137893),
+(3951,'Pembroke Pines','USA',137427),
+(3952,'Salem','USA',136924),
+(3953,'Pasadena','USA',133936),
+(3954,'Escondido','USA',133559),
+(3955,'Sunnyvale','USA',131760),
+(3956,'Savannah','USA',131510),
+(3957,'Fontana','USA',128929),
+(3958,'Orange','USA',128821),
+(3959,'Naperville','USA',128358),
+(3960,'Alexandria','USA',128283),
+(3961,'Rancho Cucamonga','USA',127743),
+(3962,'Grand Prairie','USA',127427),
+(3963,'East Los Angeles','USA',126379),
+(3964,'Fullerton','USA',126003),
+(3965,'Corona','USA',124966),
+(3966,'Flint','USA',124943),
+(3967,'Paradise','USA',124682),
+(3968,'Mesquite','USA',124523),
+(3969,'Sterling Heights','USA',124471),
+(3970,'Sioux Falls','USA',123975),
+(3971,'New Haven','USA',123626),
+(3972,'Topeka','USA',122377),
+(3973,'Concord','USA',121780),
+(3974,'Evansville','USA',121582),
+(3975,'Hartford','USA',121578),
+(3976,'Fayetteville','USA',121015),
+(3977,'Cedar Rapids','USA',120758),
+(3978,'Elizabeth','USA',120568),
+(3979,'Lansing','USA',119128),
+(3980,'Lancaster','USA',118718),
+(3981,'Fort Collins','USA',118652),
+(3982,'Coral Springs','USA',117549),
+(3983,'Stamford','USA',117083),
+(3984,'Thousand Oaks','USA',117005),
+(3985,'Vallejo','USA',116760),
+(3986,'Palmdale','USA',116670),
+(3987,'Columbia','USA',116278),
+(3988,'El Monte','USA',115965),
+(3989,'Abilene','USA',115930),
+(3990,'North Las Vegas','USA',115488),
+(3991,'Ann Arbor','USA',114024),
+(3992,'Beaumont','USA',113866),
+(3993,'Waco','USA',113726),
+(3994,'Macon','USA',113336),
+(3995,'Independence','USA',113288),
+(3996,'Peoria','USA',112936),
+(3997,'Inglewood','USA',112580),
+(3998,'Springfield','USA',111454),
+(3999,'Simi Valley','USA',111351),
+(4000,'Lafayette','USA',110257);
+INSERT INTO City VALUES
+(4001,'Gilbert','USA',109697),
+(4002,'Carrollton','USA',109576),
+(4003,'Bellevue','USA',109569),
+(4004,'West Valley City','USA',108896),
+(4005,'Clarksville','USA',108787),
+(4006,'Costa Mesa','USA',108724),
+(4007,'Peoria','USA',108364),
+(4008,'South Bend','USA',107789),
+(4009,'Downey','USA',107323),
+(4010,'Waterbury','USA',107271),
+(4011,'Manchester','USA',107006),
+(4012,'Allentown','USA',106632),
+(4013,'McAllen','USA',106414),
+(4014,'Joliet','USA',106221),
+(4015,'Lowell','USA',105167),
+(4016,'Provo','USA',105166),
+(4017,'West Covina','USA',105080),
+(4018,'Wichita Falls','USA',104197),
+(4019,'Erie','USA',103717),
+(4020,'Daly City','USA',103621),
+(4021,'Citrus Heights','USA',103455),
+(4022,'Norwalk','USA',103298),
+(4023,'Gary','USA',102746),
+(4024,'Berkeley','USA',102743),
+(4025,'Santa Clara','USA',102361),
+(4026,'Green Bay','USA',102313),
+(4027,'Cape Coral','USA',102286),
+(4028,'Arvada','USA',102153),
+(4029,'Pueblo','USA',102121),
+(4030,'Sandy','USA',101853),
+(4031,'Athens-Clarke County','USA',101489),
+(4032,'Cambridge','USA',101355),
+(4033,'Westminster','USA',100940),
+(4034,'San Buenaventura','USA',100916),
+(4035,'Portsmouth','USA',100565),
+(4036,'Livonia','USA',100545),
+(4037,'Burbank','USA',100316),
+(4038,'Clearwater','USA',99936),
+(4039,'Midland','USA',98293),
+(4040,'Davenport','USA',98256),
+(4041,'Mission Viejo','USA',98049),
+(4042,'Miami Beach','USA',97855),
+(4043,'Sunrise Manor','USA',95362),
+(4044,'New Bedford','USA',94780),
+(4045,'El Cajon','USA',94578),
+(4046,'Norman','USA',94193),
+(4047,'Richmond','USA',94100),
+(4048,'Albany','USA',93994),
+(4049,'Brockton','USA',93653),
+(4050,'Roanoke','USA',93357),
+(4051,'Billings','USA',92988),
+(4052,'Compton','USA',92864),
+(4053,'Gainesville','USA',92291),
+(4054,'Fairfield','USA',92256),
+(4055,'Arden-Arcade','USA',92040),
+(4056,'San Mateo','USA',91799),
+(4057,'Visalia','USA',91762),
+(4058,'Boulder','USA',91238),
+(4059,'Cary','USA',91213),
+(4060,'Santa Monica','USA',91084),
+(4061,'Fall River','USA',90555),
+(4062,'Kenosha','USA',89447),
+(4063,'Elgin','USA',89408),
+(4064,'Odessa','USA',89293),
+(4065,'Carson','USA',89089),
+(4066,'Charleston','USA',89063),
+(4067,'Charlotte Amalie','VIR',13000),
+(4068,'Harare','ZWE',1410000),
+(4069,'Bulawayo','ZWE',621742),
+(4070,'Chitungwiza','ZWE',274912),
+(4071,'Mount Darwin','ZWE',164362),
+(4072,'Mutare','ZWE',131367),
+(4073,'Gweru','ZWE',128037),
+(4074,'Gaza','PSE',353632),
+(4075,'Khan Yunis','PSE',123175),
+(4076,'Hebron','PSE',119401),
+(4077,'Jabaliya','PSE',113901),
+(4078,'Nablus','PSE',100231),
+(4079,'Rafah','PSE',92020);
+
+# Table CountryLanguage
+
+INSERT INTO CountryLanguage VALUES
+('AFG','Pashto',52.4),
+('NLD','Dutch',95.6),
+('ANT','Papiamento',86.2),
+('ALB','Albaniana',97.9),
+('DZA','Arabic',86.0),
+('ASM','Samoan',90.6),
+('AND','Spanish',44.6),
+('AGO','Ovimbundu',37.2),
+('AIA','English',0.0),
+('ATG','Creole English',95.7),
+('ARE','Arabic',42.0),
+('ARG','Spanish',96.8),
+('ARM','Armenian',93.4),
+('ABW','Papiamento',76.7),
+('AUS','English',81.2),
+('AZE','Azerbaijani',89.0),
+('BHS','Creole English',89.7),
+('BHR','Arabic',67.7),
+('BGD','Bengali',97.7),
+('BRB','Bajan',95.1),
+('BEL','Dutch',59.2),
+('BLZ','English',50.8),
+('BEN','Fon',39.8),
+('BMU','English',100.0),
+('BTN','Dzongkha',50.0),
+('BOL','Spanish',87.7),
+('BIH','Serbo-Croatian',99.2),
+('BWA','Tswana',75.5),
+('BRA','Portuguese',97.5),
+('GBR','English',97.3),
+('VGB','English',0.0),
+('BRN','Malay',45.5),
+('BGR','Bulgariana',83.2),
+('BFA','Mossi',50.2),
+('BDI','Kirundi',98.1),
+('CYM','English',0.0),
+('CHL','Spanish',89.7),
+('COK','Maori',0.0),
+('CRI','Spanish',97.5),
+('DJI','Somali',43.9),
+('DMA','Creole English',100.0),
+('DOM','Spanish',98.0),
+('ECU','Spanish',93.0),
+('EGY','Arabic',98.8),
+('SLV','Spanish',100.0),
+('ERI','Tigrinja',49.1),
+('ESP','Spanish',74.4),
+('ZAF','Zulu',22.7),
+('ETH','Oromo',31.0),
+('FLK','English',0.0),
+('FJI','Fijian',50.8),
+('PHL','Pilipino',29.3),
+('FRO','Faroese',100.0),
+('GAB','Fang',35.8),
+('GMB','Malinke',34.1),
+('GEO','Georgiana',71.7),
+('GHA','Akan',52.4),
+('GIB','English',88.9),
+('GRD','Creole English',100.0),
+('GRL','Greenlandic',87.5),
+('GLP','Creole French',95.0),
+('GUM','English',37.5),
+('GTM','Spanish',64.7),
+('GIN','Ful',38.6),
+('GNB','Crioulo',36.4),
+('GUY','Creole English',96.4),
+('HTI','Haiti Creole',100.0),
+('HND','Spanish',97.2),
+('HKG','Canton Chinese',88.7),
+('SJM','Norwegian',0.0),
+('IDN','Javanese',39.4),
+('IND','Hindi',39.9),
+('IRQ','Arabic',77.2),
+('IRN','Persian',45.7),
+('IRL','English',98.4),
+('ISL','Icelandic',95.7),
+('ISR','Hebrew',63.1),
+('ITA','Italian',94.1),
+('TMP','Sunda',0.0),
+('AUT','German',92.0),
+('JAM','Creole English',94.2),
+('JPN','Japanese',99.1),
+('YEM','Arabic',99.6),
+('JOR','Arabic',97.9),
+('CXR','Chinese',0.0),
+('YUG','Serbo-Croatian',75.2),
+('KHM','Khmer',88.6),
+('CMR','Fang',19.7),
+('CAN','English',60.4),
+('CPV','Crioulo',100.0),
+('KAZ','Kazakh',46.0),
+('KEN','Kikuyu',20.9),
+('CAF','Gbaya',23.8),
+('CHN','Chinese',92.0),
+('KGZ','Kirgiz',59.7),
+('KIR','Kiribati',98.9),
+('COL','Spanish',99.0),
+('COM','Comorian',75.0),
+('COG','Kongo',51.5),
+('COD','Luba',18.0),
+('CCK','Malay',0.0),
+('PRK','Korean',99.9),
+('KOR','Korean',99.9),
+('GRC','Greek',98.5),
+('HRV','Serbo-Croatian',95.9),
+('CUB','Spanish',100.0),
+('KWT','Arabic',78.1),
+('CYP','Greek',74.1),
+('LAO','Lao',67.2),
+('LVA','Latvian',55.1),
+('LSO','Sotho',85.0),
+('LBN','Arabic',93.0),
+('LBR','Kpelle',19.5),
+('LBY','Arabic',96.0),
+('LIE','German',89.0),
+('LTU','Lithuanian',81.6),
+('LUX','Luxembourgish',64.4),
+('ESH','Arabic',100.0),
+('MAC','Canton Chinese',85.6),
+('MDG','Malagasy',98.9),
+('MKD','Macedonian',66.5),
+('MWI','Chichewa',58.3),
+('MDV','Dhivehi',100.0),
+('MYS','Malay',58.4),
+('MLI','Bambara',31.8),
+('MLT','Maltese',95.8),
+('MAR','Arabic',65.0),
+('MHL','Marshallese',96.8),
+('MTQ','Creole French',96.6),
+('MRT','Hassaniya',81.7),
+('MUS','Creole French',70.6),
+('MYT','Mahoré',41.9),
+('MEX','Spanish',92.1),
+('FSM','Trukese',41.6),
+('MDA','Romanian',61.9),
+('MCO','French',41.9),
+('MNG','Mongolian',78.8),
+('MSR','English',0.0),
+('MOZ','Makua',27.8),
+('MMR','Burmese',69.0),
+('NAM','Ovambo',50.7),
+('NRU','Nauru',57.5),
+('NPL','Nepali',50.4),
+('NIC','Spanish',97.6),
+('NER','Hausa',53.1),
+('NGA','Joruba',21.4),
+('NIU','Niue',0.0),
+('NFK','English',0.0),
+('NOR','Norwegian',96.6),
+('CIV','Akan',30.0),
+('OMN','Arabic',76.7),
+('PAK','Punjabi',48.2),
+('PLW','Palau',82.2),
+('PAN','Spanish',76.8),
+('PNG','Papuan Languages',78.1),
+('PRY','Spanish',55.1),
+('PER','Spanish',79.8),
+('PCN','Pitcairnese',0.0),
+('MNP','Philippene Languages',34.1),
+('PRT','Portuguese',99.0),
+('PRI','Spanish',51.3),
+('POL','Polish',97.6),
+('GNQ','Fang',84.8),
+('QAT','Arabic',40.7),
+('FRA','French',93.6),
+('GUF','Creole French',94.3),
+('PYF','Tahitian',46.4),
+('REU','Creole French',91.5),
+('ROM','Romanian',90.7),
+('RWA','Rwanda',100.0),
+('SWE','Swedish',89.5),
+('SHN','English',0.0),
+('KNA','Creole English',100.0),
+('LCA','Creole French',80.0),
+('VCT','Creole English',99.1),
+('SPM','French',0.0),
+('DEU','German',91.3),
+('SLB','Malenasian Languages',85.6),
+('ZMB','Bemba',29.7),
+('WSM','Samoan-English',52.0),
+('SMR','Italian',100.0),
+('STP','Crioulo',86.3),
+('SAU','Arabic',95.0),
+('SEN','Wolof',48.1),
+('SYC','Seselwa',91.3),
+('SLE','Mende',34.8),
+('SGP','Chinese',77.1),
+('SVK','Slovak',85.6),
+('SVN','Slovene',87.9),
+('SOM','Somali',98.3),
+('LKA','Singali',60.3),
+('SDN','Arabic',49.4),
+('FIN','Finnish',92.7),
+('SUR','Sranantonga',81.0),
+('SWZ','Swazi',89.9),
+('CHE','German',63.6),
+('SYR','Arabic',90.0),
+('TJK','Tadzhik',62.2),
+('TWN','Min',66.7),
+('TZA','Nyamwesi',21.1);
+INSERT INTO CountryLanguage VALUES
+('DNK','Danish',93.5),
+('THA','Thai',52.6),
+('TGO','Ewe',23.2),
+('TKL','Tokelau',0.0),
+('TON','Tongan',98.3),
+('TTO','English',93.5),
+('TCD','Sara',27.7),
+('CZE','Czech',81.2),
+('TUN','Arabic',69.9),
+('TUR','Turkish',87.6),
+('TKM','Turkmenian',76.7),
+('TCA','English',0.0),
+('TUV','Tuvalu',92.5),
+('UGA','Ganda',18.1),
+('UKR','Ukrainian',64.7),
+('HUN','Hungarian',98.5),
+('URY','Spanish',95.7),
+('NCL','Malenasian Languages',45.4),
+('NZL','English',87.0),
+('UZB','Uzbek',72.6),
+('BLR','Belorussian',65.6),
+('WLF','Wallis',0.0),
+('VUT','Bislama',56.6),
+('VAT','Italian',0.0),
+('VEN','Spanish',96.9),
+('RUS','Russian',86.6),
+('VNM','Vietnamese',86.8),
+('EST','Estonian',65.3),
+('USA','English',86.2),
+('VIR','English',81.7),
+('UMI','English',0.0),
+('ZWE','Shona',72.1),
+('PSE','Arabic',95.9),
+('AFG','Dari',32.1),
+('NLD','Fries',3.7),
+('ANT','English',7.8),
+('ALB','Greek',1.8),
+('DZA','Berberi',14.0),
+('ASM','English',3.1),
+('AND','Catalan',32.3),
+('AGO','Mbundu',21.6),
+('ATG','English',0.0),
+('ARE','Hindi',0.0),
+('ARG','Italian',1.7),
+('ARM','Azerbaijani',2.6),
+('ABW','English',9.5),
+('AUS','Italian',2.2),
+('AZE','Russian',3.0),
+('BHS','Creole French',10.3),
+('BHR','English',0.0),
+('BGD','Chakma',0.4),
+('BRB','English',0.0),
+('BEL','French',32.6),
+('BLZ','Spanish',31.6),
+('BEN','Joruba',12.2),
+('BTN','Nepali',34.8),
+('BOL','Ketšua',8.1),
+('BWA','Shona',12.3),
+('BRA','German',0.5),
+('GBR','Kymri',0.9),
+('BRN','Malay-English',28.8),
+('BGR','Turkish',9.4),
+('BFA','Ful',9.7),
+('BDI','French',0.0),
+('CHL','Araucan',9.6),
+('COK','English',0.0),
+('CRI','Creole English',2.0),
+('DJI','Afar',34.8),
+('DMA','Creole French',0.0),
+('DOM','Creole French',2.0),
+('ECU','Ketšua',7.0),
+('EGY','Sinaberberi',0.0),
+('SLV','Nahua',0.0),
+('ERI','Tigre',31.7),
+('ESP','Catalan',16.9),
+('ZAF','Xhosa',17.7),
+('ETH','Amhara',30.0),
+('FJI','Hindi',43.7),
+('PHL','Cebuano',23.3),
+('FRO','Danish',0.0),
+('GAB','Punu-sira-nzebi',17.1),
+('GMB','Ful',16.2),
+('GEO','Russian',8.8),
+('GHA','Mossi',15.8),
+('GIB','Arabic',7.4),
+('GRL','Danish',12.5),
+('GLP','French',0.0),
+('GUM','Chamorro',29.6),
+('GTM','Quiché',10.1),
+('GIN','Malinke',23.2),
+('GNB','Ful',16.6),
+('GUY','Caribbean',2.2),
+('HTI','French',0.0),
+('HND','Garifuna',1.3),
+('HKG','English',2.2),
+('SJM','Russian',0.0),
+('IDN','Sunda',15.8),
+('IND','Bengali',8.2),
+('IRQ','Kurdish',19.0),
+('IRN','Azerbaijani',16.8),
+('IRL','Irish',1.6),
+('ISL','English',0.0),
+('ISR','Arabic',18.0),
+('ITA','Sardinian',2.7),
+('TMP','Portuguese',0.0),
+('AUT','Serbo-Croatian',2.2),
+('JAM','Hindi',1.9),
+('JPN','Korean',0.5),
+('YEM','Soqutri',0.0),
+('JOR','Circassian',1.0),
+('CXR','English',0.0),
+('YUG','Albaniana',16.5),
+('KHM','Vietnamese',5.5),
+('CMR','Bamileke-bamum',18.6),
+('CAN','French',23.4),
+('CPV','Portuguese',0.0),
+('KAZ','Russian',34.7),
+('KEN','Luhya',13.8),
+('CAF','Banda',23.5),
+('CHN','Zhuang',1.4),
+('KGZ','Russian',16.2),
+('KIR','Tuvalu',0.5),
+('COL','Chibcha',0.4),
+('COM','Comorian-French',12.9),
+('COG','Teke',17.3),
+('COD','Kongo',16.0),
+('CCK','English',0.0),
+('PRK','Chinese',0.1),
+('KOR','Chinese',0.1),
+('GRC','Turkish',0.9),
+('HRV','Slovene',0.0),
+('KWT','English',0.0),
+('CYP','Turkish',22.4),
+('LAO','Mon-khmer',16.5),
+('LVA','Russian',32.5),
+('LSO','Zulu',15.0),
+('LBN','Armenian',5.9),
+('LBR','Bassa',13.7),
+('LBY','Berberi',1.0),
+('LIE','Italian',2.5),
+('LTU','Russian',8.1),
+('LUX','Portuguese',13.0),
+('MAC','Portuguese',2.3),
+('MDG','French',0.0),
+('MKD','Albaniana',22.9),
+('MWI','Lomwe',18.4),
+('MDV','English',0.0),
+('MYS','Chinese',9.0),
+('MLI','Ful',13.9),
+('MLT','English',2.1),
+('MAR','Berberi',33.0),
+('MHL','English',0.0),
+('MTQ','French',0.0),
+('MRT','Wolof',6.6),
+('MUS','Bhojpuri',21.1),
+('MYT','French',20.3),
+('MEX','Náhuatl',1.8),
+('FSM','Pohnpei',23.8),
+('MDA','Russian',23.2),
+('MCO','Monegasque',16.1),
+('MNG','Kazakh',5.9),
+('MOZ','Tsonga',12.4),
+('MMR','Shan',8.5),
+('NAM','Nama',12.4),
+('NRU','Kiribati',17.9),
+('NPL','Maithili',11.9),
+('NIC','Miskito',1.6),
+('NER','Songhai-zerma',21.2),
+('NGA','Hausa',21.1),
+('NIU','English',0.0),
+('NOR','English',0.5),
+('CIV','Gur',11.7),
+('OMN','Balochi',0.0),
+('PAK','Pashto',13.1),
+('PLW','Philippene Languages',9.2),
+('PAN','Creole English',14.0),
+('PNG','Malenasian Languages',20.0),
+('PRY','Guaraní',40.1),
+('PER','Ketšua',16.4),
+('MNP','Chamorro',30.0),
+('PRI','English',47.4),
+('POL','German',1.3),
+('GNQ','Bubi',8.7),
+('QAT','Urdu',0.0),
+('FRA','Arabic',2.5),
+('GUF','Indian Languages',1.9),
+('PYF','French',40.8),
+('REU','Chinese',2.8),
+('ROM','Hungarian',7.2),
+('RWA','French',0.0),
+('SWE','Finnish',2.4),
+('KNA','English',0.0),
+('LCA','English',20.0),
+('VCT','English',0.0),
+('DEU','Turkish',2.6),
+('SLB','Papuan Languages',8.6),
+('ZMB','Tongan',11.0),
+('WSM','Samoan',47.5),
+('STP','French',0.7),
+('SEN','Ful',21.7);
+INSERT INTO CountryLanguage VALUES
+('SYC','English',3.8),
+('SLE','Temne',31.8),
+('SGP','Malay',14.1),
+('SVK','Hungarian',10.5),
+('SVN','Serbo-Croatian',7.9),
+('SOM','Arabic',0.0),
+('LKA','Tamil',19.6),
+('SDN','Dinka',11.5),
+('FIN','Swedish',5.7),
+('SUR','Hindi',0.0),
+('SWZ','Zulu',2.0),
+('CHE','French',19.2),
+('SYR','Kurdish',9.0),
+('TJK','Uzbek',23.2),
+('TWN','Mandarin Chinese',20.1),
+('TZA','Swahili',8.8),
+('DNK','Turkish',0.8),
+('THA','Lao',26.9),
+('TGO','Kabyé',13.8),
+('TKL','English',0.0),
+('TON','English',0.0),
+('TTO','Hindi',3.4),
+('TCD','Arabic',12.3),
+('CZE','Moravian',12.9),
+('TUN','Arabic-French',26.3),
+('TUR','Kurdish',10.6),
+('TKM','Uzbek',9.2),
+('TUV','Kiribati',7.5),
+('UGA','Nkole',10.7),
+('UKR','Russian',32.9),
+('HUN','Romani',0.5),
+('NCL','French',34.3),
+('NZL','Maori',4.3),
+('UZB','Russian',10.9),
+('BLR','Russian',32.0),
+('WLF','Futuna',0.0),
+('VUT','English',28.3),
+('VEN','Goajiro',0.4),
+('RUS','Tatar',3.2),
+('VNM','Tho',1.8),
+('EST','Russian',27.8),
+('USA','Spanish',7.5),
+('VIR','Spanish',13.3),
+('ZWE','Ndebele',16.2),
+('PSE','Hebrew',4.1),
+('AFG','Uzbek',8.8),
+('NLD','Arabic',0.9),
+('ANT','Dutch',0.0),
+('ALB','Macedonian',0.1),
+('ASM','Tongan',3.1),
+('AND','Portuguese',10.8),
+('AGO','Kongo',13.2),
+('ARG','Indian Languages',0.3),
+('ABW','Spanish',7.4),
+('AUS','Greek',1.6),
+('AZE','Lezgian',2.3),
+('BGD','Marma',0.2),
+('BEL','Italian',2.4),
+('BLZ','Maya Languages',9.6),
+('BEN','Adja',11.1),
+('BTN','Asami',15.2),
+('BOL','Aimará',3.2),
+('BWA','San',3.5),
+('BRA','Italian',0.4),
+('GBR','Gaeli',0.1),
+('BRN','Chinese',9.3),
+('BGR','Romani',3.7),
+('BFA','Gurma',5.7),
+('BDI','Swahili',0.0),
+('CHL','Aimará',0.5),
+('CRI','Chibcha',0.3),
+('DJI','Arabic',10.6),
+('ERI','Afar',4.3),
+('ESP','Galecian',6.4),
+('ZAF','Afrikaans',14.3),
+('ETH','Tigrinja',7.2),
+('PHL','Ilocano',9.3),
+('GAB','Mpongwe',14.6),
+('GMB','Wolof',12.6),
+('GEO','Armenian',6.8),
+('GHA','Ewe',11.9),
+('GUM','Philippene Languages',19.7),
+('GTM','Cakchiquel',8.9),
+('GIN','Susu',11.0),
+('GNB','Balante',14.6),
+('GUY','Arawakan',1.4),
+('HND','Creole English',0.2),
+('HKG','Fukien',1.9),
+('IDN','Malay',12.1),
+('IND','Telugu',7.8),
+('IRQ','Azerbaijani',1.7),
+('IRN','Kurdish',9.1),
+('ISR','Russian',8.9),
+('ITA','Friuli',1.2),
+('AUT','Turkish',1.5),
+('JPN','Chinese',0.2),
+('JOR','Armenian',1.0),
+('YUG','Hungarian',3.4),
+('KHM','Chinese',3.1),
+('CMR','Duala',10.9),
+('CAN','Chinese',2.5),
+('KAZ','Ukrainian',5.0),
+('KEN','Luo',12.8),
+('CAF','Mandjia',14.8),
+('CHN','Mantšu',0.9),
+('KGZ','Uzbek',14.1),
+('COL','Creole English',0.1),
+('COM','Comorian-madagassi',5.5),
+('COG','Mboshi',11.4),
+('COD','Mongo',13.5),
+('LAO','Thai',7.8),
+('LVA','Belorussian',4.1),
+('LSO','English',0.0),
+('LBN','French',0.0),
+('LBR','Grebo',8.9),
+('LIE','Turkish',2.5),
+('LTU','Polish',7.0),
+('LUX','Italian',4.6),
+('MAC','Mandarin Chinese',1.2),
+('MKD','Turkish',4.0),
+('MWI','Yao',13.2),
+('MYS','Tamil',3.9),
+('MLI','Senufo and Minianka',12.0),
+('MRT','Tukulor',5.4),
+('MUS','French',3.4),
+('MYT','Malagasy',16.1),
+('MEX','Yucatec',1.1),
+('FSM','Mortlock',7.6),
+('MDA','Ukrainian',8.6),
+('MCO','Italian',16.1),
+('MNG','Dorbet',2.7),
+('MOZ','Sena',9.4),
+('MMR','Karen',6.2),
+('NAM','Kavango',9.7),
+('NRU','Chinese',8.5),
+('NPL','Bhojpuri',7.5),
+('NIC','Creole English',0.5),
+('NER','Tamashek',10.4),
+('NGA','Ibo',18.1),
+('NOR','Danish',0.4),
+('CIV','Malinke',11.4),
+('PAK','Sindhi',11.8),
+('PLW','English',3.2),
+('PAN','Guaymí',5.3),
+('PRY','Portuguese',3.2),
+('PER','Aimará',2.3),
+('MNP','Chinese',7.1),
+('POL','Ukrainian',0.6),
+('FRA','Portuguese',1.2),
+('PYF','Chinese',2.9),
+('REU','Comorian',2.8),
+('ROM','Romani',0.7),
+('SWE','Southern Slavic Languages',1.3),
+('DEU','Southern Slavic Languages',1.4),
+('SLB','Polynesian Languages',3.8),
+('ZMB','Nyanja',7.8),
+('WSM','English',0.6),
+('SEN','Serer',12.5),
+('SYC','French',1.3),
+('SLE','Limba',8.3),
+('SGP','Tamil',7.4),
+('SVK','Romani',1.7),
+('SVN','Hungarian',0.5),
+('LKA','Mixed Languages',19.6),
+('SDN','Nubian Languages',8.1),
+('FIN','Russian',0.4),
+('CHE','Italian',7.7),
+('TJK','Russian',9.7),
+('TWN','Hakka',11.0),
+('TZA','Hehet',6.9),
+('DNK','Arabic',0.7),
+('THA','Chinese',12.1),
+('TGO','Watyi',10.3),
+('TTO','Creole English',2.9),
+('TCD','Mayo-kebbi',11.5),
+('CZE','Slovak',3.1),
+('TUN','Arabic-French-English',3.2),
+('TUR','Arabic',1.4),
+('TKM','Russian',6.7),
+('TUV','English',0.0),
+('UGA','Kiga',8.3),
+('UKR','Romanian',0.7),
+('HUN','German',0.4),
+('NCL','Polynesian Languages',11.6),
+('UZB','Tadzhik',4.4),
+('BLR','Ukrainian',1.3),
+('VUT','French',14.2),
+('VEN','Warrau',0.1),
+('RUS','Ukrainian',1.3),
+('VNM','Thai',1.6),
+('EST','Ukrainian',2.8),
+('USA','French',0.7),
+('VIR','French',2.5),
+('ZWE','English',2.2),
+('AFG','Turkmenian',1.9),
+('NLD','Turkish',0.8),
+('AND','French',6.2),
+('AGO','Luimbe-nganguela',5.4),
+('ABW','Dutch',5.3),
+('AUS','Canton Chinese',1.1);
+INSERT INTO CountryLanguage VALUES
+('AZE','Armenian',2.0),
+('BGD','Garo',0.1),
+('BEL','Arabic',1.6),
+('BLZ','Garifuna',6.8),
+('BEN','Aizo',8.7),
+('BOL','Guaraní',0.1),
+('BWA','Khoekhoe',2.5),
+('BRA','Japanese',0.4),
+('BRN','English',3.1),
+('BGR','Macedonian',2.6),
+('BFA','Busansi',3.5),
+('CHL','Rapa nui',0.2),
+('CRI','Chinese',0.2),
+('ERI','Hadareb',3.8),
+('ESP','Basque',1.6),
+('ZAF','Northsotho',9.1),
+('ETH','Gurage',4.7),
+('PHL','Hiligaynon',9.1),
+('GAB','Mbete',13.8),
+('GMB','Diola',9.2),
+('GEO','Azerbaijani',5.5),
+('GHA','Ga-adangme',7.8),
+('GUM','Korean',3.3),
+('GTM','Kekchí',4.9),
+('GIN','Kissi',6.0),
+('GNB','Portuguese',8.1),
+('HND','Miskito',0.2),
+('HKG','Hakka',1.6),
+('IDN','Madura',4.3),
+('IND','Marathi',7.4),
+('IRQ','Assyrian',0.8),
+('IRN','Gilaki',5.3),
+('ITA','French',0.5),
+('AUT','Hungarian',0.4),
+('JPN','English',0.1),
+('YUG','Romani',1.4),
+('KHM','Tšam',2.4),
+('CMR','Ful',9.6),
+('CAN','Italian',1.7),
+('KAZ','German',3.1),
+('KEN','Kamba',11.2),
+('CAF','Ngbaka',7.5),
+('CHN','Hui',0.8),
+('KGZ','Ukrainian',1.7),
+('COL','Arawakan',0.1),
+('COM','Comorian-Arabic',1.6),
+('COG','Mbete',4.8),
+('COD','Rwanda',10.3),
+('LAO','Lao-Soung',5.2),
+('LVA','Ukrainian',2.9),
+('LBR','Gio',7.9),
+('LTU','Belorussian',1.4),
+('LUX','French',4.2),
+('MAC','English',0.5),
+('MKD','Romani',2.3),
+('MWI','Ngoni',6.7),
+('MYS','Iban',2.8),
+('MLI','Soninke',8.7),
+('MRT','Soninke',2.7),
+('MUS','Hindi',1.2),
+('MEX','Zapotec',0.6),
+('FSM','Kosrean',7.3),
+('MDA','Gagauzi',3.2),
+('MCO','English',6.5),
+('MNG','Bajad',1.9),
+('MOZ','Lomwe',7.8),
+('MMR','Rakhine',4.5),
+('NAM','Afrikaans',9.5),
+('NRU','Tuvalu',8.5),
+('NPL','Tharu',5.4),
+('NIC','Sumo',0.2),
+('NER','Ful',9.7),
+('NGA','Ful',11.3),
+('NOR','Swedish',0.3),
+('CIV','Kru',10.5),
+('PAK','Saraiki',9.8),
+('PLW','Chinese',1.6),
+('PAN','Cuna',2.0),
+('PRY','German',0.9),
+('MNP','Korean',6.5),
+('POL','Belorussian',0.5),
+('FRA','Italian',0.4),
+('REU','Malagasy',1.4),
+('ROM','German',0.4),
+('SWE','Arabic',0.8),
+('DEU','Italian',0.7),
+('ZMB','Lozi',6.4),
+('SEN','Diola',5.0),
+('SLE','Kono-vai',5.1),
+('SVK','Czech and Moravian',1.1),
+('SDN','Beja',6.4),
+('FIN','Estonian',0.2),
+('CHE','Romansh',0.6),
+('TWN','Ami',0.6),
+('TZA','Haya',5.9),
+('DNK','German',0.5),
+('THA','Malay',3.6),
+('TGO','Kotokoli',5.7),
+('TCD','Kanem-bornu',9.0),
+('CZE','Polish',0.6),
+('TKM','Kazakh',2.0),
+('UGA','Soga',8.2),
+('UKR','Bulgariana',0.3),
+('HUN','Serbo-Croatian',0.2),
+('UZB','Kazakh',3.8),
+('BLR','Polish',0.6),
+('RUS','Chuvash',0.9),
+('VNM','Muong',1.5),
+('EST','Belorussian',1.4),
+('USA','German',0.7),
+('ZWE','Nyanja',2.2),
+('AFG','Balochi',0.9),
+('AGO','Nyaneka-nkhumbi',5.4),
+('AUS','Arabic',1.0),
+('BGD','Khasi',0.1),
+('BEL','German',1.0),
+('BEN','Bariba',8.7),
+('BWA','Ndebele',1.3),
+('BRA','Indian Languages',0.2),
+('BFA','Dagara',3.1),
+('ERI','Bilin',3.0),
+('ZAF','English',8.5),
+('ETH','Somali',4.1),
+('PHL','Bicol',5.7),
+('GMB','Soninke',7.6),
+('GEO','Osseetti',2.4),
+('GHA','Gurma',3.3),
+('GUM','Japanese',2.0),
+('GTM','Mam',2.7),
+('GIN','Kpelle',4.6),
+('GNB','Malinke',6.9),
+('HKG','Chiu chau',1.4),
+('IDN','Minangkabau',2.4),
+('IND','Tamil',6.3),
+('IRQ','Persian',0.8),
+('IRN','Luri',4.3),
+('ITA','German',0.5),
+('AUT','Slovene',0.4),
+('JPN','Philippene Languages',0.1),
+('YUG','Slovak',0.7),
+('CMR','Tikar',7.4),
+('CAN','German',1.6),
+('KAZ','Uzbek',2.3),
+('KEN','Kalenjin',10.8),
+('CAF','Sara',6.4),
+('CHN','Miao',0.7),
+('KGZ','Tatar',1.3),
+('COL','Caribbean',0.1),
+('COM','Comorian-Swahili',0.5),
+('COG','Punu',2.9),
+('COD','Zande',6.1),
+('LVA','Polish',2.1),
+('LBR','Kru',7.2),
+('LTU','Ukrainian',1.1),
+('LUX','German',2.3),
+('MKD','Serbo-Croatian',2.0),
+('MYS','English',1.6),
+('MLI','Tamashek',7.3),
+('MRT','Ful',1.2),
+('MUS','Tamil',0.8),
+('MEX','Mixtec',0.6),
+('FSM','Yap',5.8),
+('MDA','Bulgariana',1.6),
+('MNG','Buryat',1.7),
+('MOZ','Shona',6.5),
+('MMR','Mon',2.4),
+('NAM','Herero',8.0),
+('NRU','English',7.5),
+('NPL','Tamang',4.9),
+('NER','Kanuri',4.4),
+('NGA','Ibibio',5.6),
+('NOR','Saame',0.0),
+('CIV','[South]Mande',7.7),
+('PAK','Urdu',7.6),
+('PAN','Embera',0.6),
+('MNP','English',4.8),
+('FRA','Spanish',0.4),
+('REU','Tamil',0.0),
+('ROM','Ukrainian',0.3),
+('SWE','Spanish',0.6),
+('DEU','Greek',0.4),
+('ZMB','Chewa',5.7),
+('SEN','Malinke',3.8),
+('SLE','Bullom-sherbro',3.8),
+('SVK','Ukrainian and Russian',0.6),
+('SDN','Nuer',4.9),
+('FIN','Saame',0.0),
+('TWN','Atayal',0.4),
+('TZA','Makonde',5.9),
+('DNK','English',0.3),
+('THA','Khmer',1.3),
+('TGO','Ane',5.7),
+('TCD','Ouaddai',8.7),
+('CZE','German',0.5),
+('UGA','Teso',6.0),
+('UKR','Hungarian',0.3),
+('HUN','Romanian',0.1),
+('UZB','Karakalpak',2.0),
+('RUS','Bashkir',0.7),
+('VNM','Chinese',1.4);
+INSERT INTO CountryLanguage VALUES
+('EST','Finnish',0.7),
+('USA','Italian',0.6),
+('AGO','Chokwe',4.2),
+('AUS','Vietnamese',0.8),
+('BGD','Santhali',0.1),
+('BEL','Turkish',0.9),
+('BEN','Somba',6.7),
+('BFA','Dyula',2.6),
+('ERI','Saho',3.0),
+('ZAF','Tswana',8.1),
+('ETH','Sidamo',3.2),
+('PHL','Waray-waray',3.8),
+('GEO','Abhyasi',1.7),
+('GHA','Joruba',1.3),
+('GIN','Yalunka',2.9),
+('GNB','Mandyako',4.9),
+('IDN','Batakki',2.2),
+('IND','Urdu',5.1),
+('IRN','Mazandarani',3.6),
+('ITA','Albaniana',0.2),
+('AUT','Polish',0.2),
+('JPN','Ainu',0.0),
+('YUG','Macedonian',0.5),
+('CMR','Mandara',5.7),
+('CAN','Polish',0.7),
+('KAZ','Tatar',2.0),
+('KEN','Gusii',6.1),
+('CAF','Mbum',6.4),
+('CHN','Uighur',0.6),
+('KGZ','Kazakh',0.8),
+('COG','Sango',2.6),
+('COD','Ngala and Bangi',5.8),
+('LVA','Lithuanian',1.2),
+('LBR','Mano',7.2),
+('MYS','Dusun',1.1),
+('MLI','Songhai',6.9),
+('MRT','Zenaga',1.2),
+('MUS','Marathi',0.7),
+('MEX','Otomí',0.4),
+('FSM','Wolea',3.7),
+('MNG','Dariganga',1.4),
+('MOZ','Tswa',6.0),
+('MMR','Chin',2.2),
+('NAM','Caprivi',4.7),
+('NPL','Newari',3.7),
+('NGA','Kanuri',4.1),
+('PAK','Balochi',3.0),
+('PAN','Arabic',0.6),
+('MNP','Carolinian',4.8),
+('FRA','Turkish',0.4),
+('ROM','Serbo-Croatian',0.1),
+('SWE','Norwegian',0.5),
+('DEU','Polish',0.3),
+('ZMB','Nsenga',4.3),
+('SEN','Soninke',1.3),
+('SLE','Ful',3.8),
+('SDN','Zande',2.7),
+('TWN','Paiwan',0.3),
+('TZA','Nyakusa',5.4),
+('DNK','Swedish',0.3),
+('THA','Kuy',1.1),
+('TGO','Moba',5.4),
+('TCD','Hadjarai',6.7),
+('CZE','Silesiana',0.4),
+('UGA','Lango',5.9),
+('UKR','Belorussian',0.3),
+('HUN','Slovak',0.1),
+('UZB','Tatar',1.8),
+('RUS','Chechen',0.6),
+('VNM','Khmer',1.4),
+('USA','Chinese',0.6),
+('AGO','Luvale',3.6),
+('AUS','Serbo-Croatian',0.6),
+('BGD','Tripuri',0.1),
+('BEN','Ful',5.6),
+('ZAF','Southsotho',7.6),
+('ETH','Walaita',2.8),
+('PHL','Pampango',3.0),
+('GIN','Loma',2.3),
+('IDN','Bugi',2.2),
+('IND','Gujarati',4.8),
+('IRN','Balochi',2.3),
+('ITA','Slovene',0.2),
+('AUT','Czech',0.2),
+('CMR','Maka',4.9),
+('CAN','Spanish',0.7),
+('KEN','Meru',5.5),
+('CHN','Yi',0.6),
+('KGZ','Tadzhik',0.8),
+('COD','Rundi',3.8),
+('LBR','Loma',5.8),
+('MOZ','Chuabo',5.7),
+('MMR','Kachin',1.4),
+('NAM','San',1.9),
+('NPL','Hindi',3.0),
+('NGA','Edo',3.3),
+('PAK','Hindko',2.4),
+('SLE','Kuranko',3.4),
+('SDN','Bari',2.5),
+('TZA','Chaga and Pare',4.9),
+('DNK','Norwegian',0.3),
+('TGO','Naudemba',4.1),
+('TCD','Tandjile',6.5),
+('CZE','Romani',0.3),
+('UGA','Lugbara',4.7),
+('UKR','Polish',0.1),
+('RUS','Mordva',0.5),
+('VNM','Nung',1.1),
+('USA','Tagalog',0.4),
+('AGO','Ambo',2.4),
+('AUS','German',0.6),
+('ZAF','Tsonga',4.3),
+('PHL','Pangasinan',1.8),
+('IDN','Banja',1.8),
+('IND','Kannada',3.9),
+('IRN','Arabic',2.2),
+('ITA','Romani',0.2),
+('AUT','Romanian',0.2),
+('CMR','Masana',3.9),
+('CAN','Portuguese',0.7),
+('KEN','Nyika',4.8),
+('CHN','Tujia',0.5),
+('COD','Teke',2.7),
+('LBR','Malinke',5.1),
+('MOZ','Ronga',3.7),
+('MMR','Kayah',0.4),
+('NAM','German',0.9),
+('NGA','Tiv',2.3),
+('PAK','Brahui',1.2),
+('SLE','Yalunka',3.4),
+('SDN','Fur',2.1),
+('TZA','Luguru',4.9),
+('TGO','Gurma',3.4),
+('TCD','Gorane',6.2),
+('CZE','Hungarian',0.2),
+('UGA','Gisu',4.5),
+('RUS','Kazakh',0.4),
+('VNM','Miao',0.9),
+('USA','Polish',0.3),
+('AGO','Luchazi',2.4),
+('ZAF','Swazi',2.5),
+('PHL','Maguindanao',1.4),
+('IDN','Bali',1.7),
+('IND','Malajalam',3.6),
+('IRN','Bakhtyari',1.7),
+('CAN','Punjabi',0.7),
+('KEN','Masai',1.6),
+('CHN','Mongolian',0.4),
+('COD','Boa',2.3),
+('MOZ','Marendje',3.5),
+('NGA','Ijo',1.8),
+('SDN','Chilluk',1.7),
+('TZA','Shambala',4.3),
+('UGA','Acholi',4.4),
+('RUS','Avarian',0.4),
+('VNM','Man',0.7),
+('USA','Korean',0.3),
+('ZAF','Venda',2.2),
+('PHL','Maranao',1.3),
+('IND','Orija',3.3),
+('IRN','Turkmenian',1.6),
+('CAN','Ukrainian',0.6),
+('KEN','Turkana',1.4),
+('CHN','Tibetan',0.4),
+('COD','Chokwe',1.8),
+('MOZ','Nyanja',3.3),
+('NGA','Bura',1.6),
+('SDN','Lotuko',1.5),
+('TZA','Gogo',3.9),
+('UGA','Rwanda',3.2),
+('RUS','Mari',0.4),
+('USA','Vietnamese',0.2),
+('ZAF','Ndebele',1.5),
+('IND','Punjabi',2.8),
+('CAN','Dutch',0.5),
+('CHN','Puyi',0.2),
+('TZA','Ha',3.5),
+('RUS','Udmur',0.3),
+('USA','Japanese',0.2),
+('IND','Asami',1.5),
+('CAN','Eskimo Languages',0.1),
+('CHN','Dong',0.2),
+('RUS','Belorussian',0.3),
+('USA','Portuguese',0.2);
+
+ANALYZE TABLE Country, City, CountryLanguage;
diff --git a/mysql-test/include/world_schema.inc b/mysql-test/include/world_schema.inc
new file mode 100644
index 00000000000..b2161afbb0a
--- /dev/null
+++ b/mysql-test/include/world_schema.inc
@@ -0,0 +1,25 @@
+CREATE TABLE Country (
+ Code char(3) NOT NULL default '',
+ Name char(52) NOT NULL default '',
+ SurfaceArea float(10,2) NOT NULL default '0.00',
+ Population int(11) NOT NULL default '0',
+ Capital int(11) default NULL,
+ PRIMARY KEY (Code),
+ UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ ID int(11) NOT NULL auto_increment,
+ Name char(35) NOT NULL default '',
+ Country char(3) NOT NULL default '',
+ Population int(11) NOT NULL default '0',
+ PRIMARY KEY (ID),
+ INDEX (Population),
+ INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+ Country char(3) NOT NULL default '',
+ Language char(30) NOT NULL default '',
+ Percentage float(3,1) NOT NULL default '0.0',
+ PRIMARY KEY (Country, Language),
+ INDEX (Percentage)
+);
diff --git a/mysql-test/include/world_schema1.inc b/mysql-test/include/world_schema1.inc
new file mode 100644
index 00000000000..172e79a7c8c
--- /dev/null
+++ b/mysql-test/include/world_schema1.inc
@@ -0,0 +1,18 @@
+CREATE TABLE Country (
+ Code char(3) NOT NULL default '',
+ Name char(52) NOT NULL default '',
+ SurfaceArea float(10,2) NOT NULL default '0.00',
+ Population int(11) NOT NULL default '0',
+ Capital int(11) default NULL
+);
+CREATE TABLE City (
+ ID int(11) NOT NULL,
+ Name char(35) NOT NULL default '',
+ Country char(3) NOT NULL default '',
+ Population int(11) NOT NULL default '0'
+);
+CREATE TABLE CountryLanguage (
+ Country char(3) NOT NULL default '',
+ Language char(30) NOT NULL default '',
+ Percentage float(3,1) NOT NULL default '0.0'
+);
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 962f0553b01..3df3c33ceb1 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -142,7 +142,9 @@ my $path_config_file; # The generated config file, var/my.cnf
# executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
-my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,handler,parts,innodb,innodb_plugin,percona,ndb,vcol,oqgraph,sphinx";
+my $DEFAULT_SUITES="main,binlog,federated,rpl,maria,handler,parts,innodb," .
+ "innodb_plugin,percona,ndb,vcol,oqgraph,sphinx," .
+ "optimizer_unfixed_bugs";
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
diff --git a/mysql-test/r/archive_gis.result b/mysql-test/r/archive_gis.result
index 178c5716911..af231ad6ce4 100644
--- a/mysql-test/r/archive_gis.result
+++ b/mysql-test/r/archive_gis.result
@@ -403,7 +403,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result
index 796821a87bd..75a6a38fadc 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/compress.result b/mysql-test/r/compress.result
index 1d3752f09e7..4c1c49bf3e0 100644
--- a/mysql-test/r/compress.result
+++ b/mysql-test/r/compress.result
@@ -189,37 +189,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1395,15 +1395,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1419,15 +1419,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1435,7 +1435,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index e871d9526ca..aab2ba0cad7 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -104,7 +104,7 @@ insert into t1 (b) values ("hello"),("my"),("world");
create table t2 (key (b)) select * from t1;
explain select * from t2 where b="world";
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref B B 21 const 1 Using where
+1 SIMPLE t2 ref B B 21 const 1 Using index condition
select * from t2 where b="world";
a B
3 world
diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result
index b42094550bd..51e3cb779e2 100644
--- a/mysql-test/r/ctype_collate.result
+++ b/mysql-test/r/ctype_collate.result
@@ -566,31 +566,31 @@ INSERT INTO t1 VALUES ('i','i');
INSERT INTO t1 VALUES ('j','j');
EXPLAIN SELECT * FROM t1 WHERE s1='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref s1 s1 11 const 1 Using where
+1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
EXPLAIN SELECT * FROM t1 WHERE s2='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref s2 s2 11 const 1 Using where
+1 SIMPLE t1 ref s2 s2 11 const 1 Using index condition
EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref s1 s1 11 const 1 Using where
+1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range s1 s1 11 NULL 2 Using where
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range s1 s1 11 NULL 2 Using where
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range s1 s1 11 NULL 1 Using where
+1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
diff --git a/mysql-test/r/ctype_eucjpms.result b/mysql-test/r/ctype_eucjpms.result
index 21aa38b7fe6..21aa38b7fe6 100755..100644
--- a/mysql-test/r/ctype_eucjpms.result
+++ b/mysql-test/r/ctype_eucjpms.result
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 63f199ad3e8..64677804646 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1537,7 +1537,7 @@ explain
select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Y ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
-1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where; Using join buffer
+1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
substr(Z.a,-1) a
3 123
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 80f04ffd455..e707f01edbf 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -58,7 +58,7 @@ a b a b
explain select * from t1 as x1, (select * from t1) as x2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY x1 ALL NULL NULL NULL NULL 4
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 4
drop table if exists t2,t3;
select * from (select 1) as a;
@@ -189,13 +189,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 NULL NULL NULL 6 Using where; Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
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 NULL NULL NULL 6 Using where; Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
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;
@@ -246,7 +246,7 @@ a a
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
-1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 2
5 UNION t1 ALL NULL NULL NULL NULL 2
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
@@ -313,7 +313,7 @@ explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
2 DERIVED x ALL NULL NULL NULL NULL 17 Using temporary; Using filesort
-2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer
+2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
drop table t1;
create table t2 (a int, b int, primary key (a));
insert into t2 values (1,7),(2,7);
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index b1cb70fa43c..ac87ea049a0 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -173,9 +173,9 @@ INSERT INTO t2 values (1),(2),(3);
INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2');
explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using temporary
-1 SIMPLE t3 ref a a 5 test.t1.b 2 Using where; Using index
-1 SIMPLE t2 index a a 4 NULL 5 Using where; Using index; Distinct; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using where; Using temporary
+1 SIMPLE t3 ref a a 5 test.t1.b 2 Using index
+1 SIMPLE t2 index a a 4 NULL 5 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
a
1
@@ -190,7 +190,7 @@ insert into t3 select * from t4;
explain select distinct t1.a from t1,t3 where t1.a=t3.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 4 Using index; Using temporary
-1 SIMPLE t3 ref a a 5 test.t1.a 11 Using where; Using index; Distinct
+1 SIMPLE t3 ref a a 5 test.t1.a 11 Using index; Distinct
select distinct t1.a from t1,t3 where t1.a=t3.a;
a
1
@@ -300,11 +300,11 @@ WHERE
AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index id id 4 NULL 2 Using index; Using temporary
-1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer
-1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer
-1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
+1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
+1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
+1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
1 SIMPLE t2_lj ref id id 4 test.j_lj_t2.id 1 Using where; Using index; Distinct
-1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
+1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
1 SIMPLE t3_lj ref id id 4 test.j_lj_t3.id 1 Using where; Using index; Distinct
SELECT DISTINCT
t1.id
@@ -515,7 +515,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1_1 ALL NULL NULL NULL NULL 3 Using temporary
-1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer
+1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer (flat, BNL join)
EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
WHERE t1_1.a = t1_2.a;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 4bc6c0409f3..25fc524bc9b 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -13,7 +13,7 @@ id str
3 foo
explain select * from t1 where str is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref str str 11 const 1 Using where
+1 SIMPLE t1 ref str str 11 const 1 Using index condition
explain select * from t1 where str="foo";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const str str 11 const 1
@@ -50,7 +50,7 @@ insert into ÔÁÂ (ËÏÌ0) values (1);
insert into ÔÁÂ (ËÏÌ0) values (2);
explain select ËÏÌ0 from ÔÁÂ where ËÏÌ0=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using where; Using index
+1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using index
drop table ÔÁÂ;
set names latin1;
select 3 into @v1;
@@ -116,7 +116,7 @@ FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
EXPLAIN EXTENDED SELECT 1
@@ -124,7 +124,7 @@ FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
prepare s1 from
@@ -134,7 +134,7 @@ execute s1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
prepare s1 from
@@ -144,14 +144,14 @@ execute s1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
execute s1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
DROP TABLE t1,t2;
@@ -195,16 +195,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; Using join buffer (flat, BNL join)
flush tables;
SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
dt
flush tables;
EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
-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; Using join buffer (flat, BNL join)
flush tables;
SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
dt
@@ -224,7 +224,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 `test`.`t1`
+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 `test`.`t1`
DROP TABLE t1, t2;
#
# Bug #48419: another explain crash..
diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result
index fae8979a6e7..925158ab129 100644
--- a/mysql-test/r/func_concat.result
+++ b/mysql-test/r/func_concat.result
@@ -118,7 +118,7 @@ EXPLAIN SELECT CONCAT('gui_', t2.a), t1.d FROM t2
LEFT JOIN t1 ON t1.a = CONCAT('gui_', t2.a) AND t1.b = 'a' AND t1.c = 'b';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL PRIMARY 102 NULL 3 Using index
-1 SIMPLE t1 eq_ref PRIMARY,a PRIMARY 318 func,const,const 1
+1 SIMPLE t1 eq_ref PRIMARY,a PRIMARY 318 func,const,const 1 Using where
DROP TABLE t1, t2;
#
# Bug #50096: CONCAT_WS inside procedure returning wrong data
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index de592ece285..adadbb14444 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -986,7 +986,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort; Distinct
-2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer
+2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select distinct group_concat(`test`.`td`.`f1` separator ',') AS `GROUP_CONCAT(td.f1)` from `test`.`t1` join `test`.`t1` `td` group by `test`.`td`.`f1`) `d` join `test`.`t1`
SELECT 1 FROM
@@ -1007,7 +1007,7 @@ t1 t2, t1 GROUP BY t1.a) AS d;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select group_concat(`test`.`t1`.`a` order by `test`.`t1`.`a` ASC separator ',') AS `GROUP_CONCAT(t1.a ORDER BY t1.a ASC)` from `test`.`t1` `t2` join `test`.`t1` group by `test`.`t1`.`a`) `d`
DROP TABLE t1;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 606f879b47f..44025842243 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -614,7 +614,7 @@ explain
select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range k1 k1 7 NULL 1 Using where; Using index
-1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index; Using join buffer
+1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
explain
select min(a4 - 0.01) from t1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -651,7 +651,7 @@ explain
select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range k2 k2 4 NULL 6 Using where; Using index
-1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer
+1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer (flat, BNL join)
drop table t1, t2;
create table t1 (a char(10));
insert into t1 values ('a'),('b'),('c');
@@ -1333,7 +1333,7 @@ CREATE TABLE t2( a INT, b INT, c INT, KEY(a, b) );
INSERT INTO t2 ( a, b, c ) VALUES ( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 );
EXPLAIN SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 5 const 2 Using where
+1 SIMPLE t2 ref a a 5 const 2
SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1;
MIN(b) MIN(c)
3 2
diff --git a/mysql-test/r/func_group_innodb.result b/mysql-test/r/func_group_innodb.result
index 908e85c1652..11d8e390f1d 100644
--- a/mysql-test/r/func_group_innodb.result
+++ b/mysql-test/r/func_group_innodb.result
@@ -79,7 +79,7 @@ min(7)
explain select min(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
-1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
select min(7) from t2i join t1i;
min(7)
NULL
@@ -95,7 +95,7 @@ max(7)
explain select max(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
-1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
select max(7) from t2i join t1i;
max(7)
NULL
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index fdeec2755ca..3ca4d9c2da5 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -241,7 +241,7 @@ insert into t2 select C.a*2+1, 'yes' from t1 C;
explain
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 5 NULL 12 Using where
+1 SIMPLE t2 range a a 5 NULL 12 Using index condition; Using MRR
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
a filler
1 yes
@@ -256,10 +256,10 @@ a filler
19 yes
explain select * from t2 force index(a) where a NOT IN (2,2,2,2,2,2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 5 NULL 912 Using where
+1 SIMPLE t2 range a a 5 NULL 912 Using index condition; Using MRR
explain select * from t2 force index(a) where a <> 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 5 NULL 912 Using where
+1 SIMPLE t2 range a a 5 NULL 912 Using index condition; Using MRR
drop table t2;
create table t2 (a datetime, filler char(200), key(a));
insert into t2 select '2006-04-25 10:00:00' + interval C.a minute,
@@ -271,7 +271,7 @@ select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 9 NULL 18 Using where
+1 SIMPLE t2 range a a 9 NULL 18 Using index condition; Using MRR
select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
@@ -295,7 +295,7 @@ insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'),
('barbas','1'), ('bazbazbay', '1'),('zz','1');
explain select * from t2 where a not in('foo','barbar', 'bazbazbaz');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 13 NULL 7 Using where
+1 SIMPLE t2 range a a 13 NULL 7 Using index condition; Using MRR
drop table t2;
create table t2 (a decimal(10,5), filler char(200), key(a));
insert into t2 select 345.67890, 'no' from t1 A, t1 B;
@@ -306,7 +306,7 @@ insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'),
explain
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 7 NULL 7 Using where
+1 SIMPLE t2 range a a 7 NULL 7 Using index condition; Using MRR
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
a filler
0.00000 1
@@ -630,16 +630,16 @@ INSERT INTO t1 (c_int) SELECT 0 FROM t1;
INSERT INTO t1 (c_int) SELECT 0 FROM t1;
EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, NULL, 2, NULL, 3, NULL);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -648,10 +648,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where
+1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where
+1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -660,10 +660,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_float IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where
+1 SIMPLE t1 range c_float c_float 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where
+1 SIMPLE t1 range c_float c_float 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -672,10 +672,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_bit IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where
+1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where
+1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -685,11 +685,11 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE c_date
IN ('2009-09-01', '2009-09-02', '2009-09-03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where
+1 SIMPLE t1 range c_date c_date 3 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_date
IN (NULL, '2009-09-01', '2009-09-02', '2009-09-03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where
+1 SIMPLE t1 range c_date c_date 3 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -699,11 +699,11 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE c_datetime
IN ('2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where
+1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_datetime
IN (NULL, '2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where
+1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -713,11 +713,11 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE c_timestamp
IN ('2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where
+1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_timestamp
IN (NULL, '2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where
+1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -726,10 +726,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_year IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where
+1 SIMPLE t1 range c_year c_year 1 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where
+1 SIMPLE t1 range c_year c_year 1 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -738,10 +738,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_char IN ('1', '2', '3');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where
+1 SIMPLE t1 range c_char c_char 10 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, '1', '2', '3');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where
+1 SIMPLE t1 range c_char c_char 10 NULL 3 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 4268268fabb..c50e3757600 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2550,12 +2550,12 @@ insert into t1 values (-1),(null);
explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 2
explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 2
drop table t1;
#
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 3b18ee61336..112ca44396f 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -395,7 +395,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
diff --git a/mysql-test/r/greedy_optimizer.result b/mysql-test/r/greedy_optimizer.result
index c0012c297d1..b4844785318 100644
--- a/mysql-test/r/greedy_optimizer.result
+++ b/mysql-test/r/greedy_optimizer.result
@@ -121,11 +121,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -133,59 +133,59 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -201,11 +201,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -213,59 +213,59 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 289.418727
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -277,11 +277,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -289,60 +289,60 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
@@ -353,11 +353,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -365,59 +365,59 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 289.418727
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -433,11 +433,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -445,59 +445,59 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -509,11 +509,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -521,60 +521,60 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
@@ -585,11 +585,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -597,59 +597,59 @@ Last_query_cost 821.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 821.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 794.837037
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 95f0bbbe36a..f22a8b0fb55 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -537,11 +537,11 @@ a b
explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary
-1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4);
@@ -873,7 +873,7 @@ explain
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
where t2.b=v1.a GROUP BY t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index b b 2 NULL 10 Using index
+1 SIMPLE t2 index b b 2 NULL 10 Using where; Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 1 test.t2.b 1
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
where t2.b=v1.a GROUP BY t2.b;
@@ -1542,8 +1542,9 @@ 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 subselect2 eq_ref unique_key unique_key 4 func 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 144
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;
@@ -1555,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)
SHOW VARIABLES LIKE 'old';
Variable_name Value
old OFF
@@ -1742,7 +1743,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
@@ -1750,7 +1751,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;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 6fef66b9d93..974521ec120 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -2256,7 +2256,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index
-2 DEPENDENT SUBQUERY t1 index NULL a 10 NULL 1 Using index
+2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
@@ -2267,7 +2267,7 @@ ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2)
AND t1_outer1.b = t1_outer2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
-1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
+1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
@@ -2444,7 +2444,7 @@ a b
3 13
explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY,index PRIMARY 4 NULL 3 100.00 Using where; Using index for group-by; Using temporary
+1 SIMPLE t1 ref PRIMARY,index PRIMARY 4 const 15 100.00 Using index; Using temporary
Warnings:
Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a`
drop table t1;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index ddf675e2f73..fe0f5f39aca 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -204,7 +204,7 @@ key a (a)
INSERT INTO t1 VALUES (10), (10), (10);
EXPLAIN SELECT * FROM t1 WHERE a=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 3 Using where
+1 SIMPLE t1 ref a a 5 const 3
SELECT * FROM t1 WHERE a=10;
a
10
diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
index 7ad0f212d99..fb26f98cdaf 100644
--- a/mysql-test/r/heap_btree.result
+++ b/mysql-test/r/heap_btree.result
@@ -344,3 +344,38 @@ INSERT INTO t1 VALUES(1),(1);
DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a;
DROP TABLE t1;
End of 5.0 tests
+# bit index in heap tables
+create table t1 (a bit(63) not null) engine=heap;
+insert into t1 values (869751),(736494),(226312),(802616),(728912);
+alter table t1 add unique uniq_id using BTREE (a);
+select 0+a from t1 where a > 736494;
+0+a
+802616
+869751
+explain select 0+a from t1 where a > 736494;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uniq_id uniq_id 8 NULL 3 Using where
+select 0+a from t1 where a = 736494;
+0+a
+736494
+explain select 0+a from t1 where a = 736494;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const uniq_id uniq_id 8 const 1
+select 0+a from t1 where a=869751 or a=736494;
+0+a
+736494
+869751
+explain select 0+a from t1 where a=869751 or a=736494;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uniq_id uniq_id 8 NULL 2 Using where
+select 0+a from t1 where a in (869751,736494,226312,802616);
+0+a
+226312
+736494
+802616
+869751
+explain select 0+a from t1 where a in (869751,736494,226312,802616);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uniq_id uniq_id 8 NULL 4 Using where
+drop table t1;
+End of 5.3 tests
diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result
index bae49af462f..ba7d79e491a 100644
--- a/mysql-test/r/heap_hash.result
+++ b/mysql-test/r/heap_hash.result
@@ -382,3 +382,38 @@ INSERT INTO t1 VALUES('A ', 'A ');
ERROR 23000: Duplicate entry 'A -A ' for key 'key1'
DROP TABLE t1;
End of 5.0 tests
+# bit index in heap tables
+create table t1 (a bit(63) not null) engine=heap;
+insert into t1 values (869751),(736494),(226312),(802616),(728912);
+alter table t1 add unique uniq_id using HASH (a);
+select 0+a from t1 where a > 736494;
+0+a
+869751
+802616
+explain select 0+a from t1 where a > 736494;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL uniq_id NULL NULL NULL 5 Using where
+select 0+a from t1 where a = 736494;
+0+a
+736494
+explain select 0+a from t1 where a = 736494;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const uniq_id uniq_id 8 const 1
+select 0+a from t1 where a=869751 or a=736494;
+0+a
+736494
+869751
+explain select 0+a from t1 where a=869751 or a=736494;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uniq_id uniq_id 8 NULL 2 Using where
+select 0+a from t1 where a in (869751,736494,226312,802616);
+0+a
+226312
+736494
+802616
+869751
+explain select 0+a from t1 where a in (869751,736494,226312,802616);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uniq_id uniq_id 8 NULL 4 Using where
+drop table t1;
+End of 5.3 tests
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index df570e1f4ae..e5ace9b92fc 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -19,7 +19,7 @@ Table Op Msg_type Msg_text
test.t0 analyze status OK
explain select * from t0 where key1 < 3 or key1 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1 i1 4 NULL 78 Using where
+1 SIMPLE t0 range i1 i1 4 NULL 78 Using index condition; Using MRR
explain
select * from t0 where key1 < 3 or key2 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
@@ -72,7 +72,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 17 Using sort_union(i1,i2); Using where
explain select * from t0 where key2 = 45 or key1 <=> null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1,i2 i2 4 NULL 1 Using where
+1 SIMPLE t0 range i1,i2 i2 4 NULL 1 Using where; Using MRR
explain select * from t0 where key2 = 45 or key1 is not null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL i1,i2 NULL NULL NULL 1024 Using where
@@ -115,7 +115,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t0 where
(key1 < 3 or key2 < 3) and (key3 < 100);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1,i2,i3 i3 4 NULL 95 Using where
+1 SIMPLE t0 range i1,i2,i3 i3 4 NULL 95 Using index condition; Using where; Using MRR
explain select * from t0 where
(key1 < 3 or key2 < 3) and (key3 < 1000);
id select_type table type possible_keys key key_len ref rows Extra
@@ -271,11 +271,11 @@ explain select * from t0,t1 where t0.key1 = 5 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ref i1 i1 4 const 1
-1 SIMPLE t1 index_merge i1,i8 i1,i8 4,4 NULL 2 Using union(i1,i8); Using where; Using join buffer
+1 SIMPLE t1 index_merge i1,i8 i1,i8 4,4 NULL 2 Using union(i1,i8); Using where; Using join buffer (flat, BNL join)
explain select * from t0,t1 where t0.key1 < 3 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1 i1 4 NULL 3 Using where
+1 SIMPLE t0 range i1 i1 4 NULL 3 Using index condition; Using MRR
1 SIMPLE t1 ALL i1,i8 NULL NULL NULL 1024 Range checked for each record (index map: 0x81)
explain select * from t1 where key1=3 or key2=4
union select * from t1 where key1<4 or key3=5;
@@ -342,15 +342,13 @@ create table t4 (a int);
insert into t4 values (1),(4),(3);
set @save_join_buffer_size=@@join_buffer_size;
set join_buffer_size= 4000;
-Warnings:
-Warning 1292 Truncated incorrect join_buffer_size value: '4000'
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
where (A.key1 < 500000 or A.key2 < 3)
and (B.key1 < 500000 or B.key2 < 3);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where
-1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where; Using join buffer
+1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where; Using join buffer (flat, BNL join)
select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
where (A.key1 < 500000 or A.key2 < 3)
@@ -364,7 +362,7 @@ where (A.key1 = 1 or A.key2 = 1)
and (B.key1 = 1 or B.key2 = 1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where
-1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where; Using join buffer
+1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where; Using join buffer (flat, BNL join)
select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
where (A.key1 = 1 or A.key2 = 1)
@@ -379,7 +377,7 @@ where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.
and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where
-1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where; Using join buffer
+1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where; Using join buffer (flat, BNL join)
select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A, t0 as B
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1)
@@ -1381,19 +1379,19 @@ primary key (pk1, pk2)
);
explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 7 Using where
+1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 7 Using index condition; Using where; Using MRR
select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2
-1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2
-1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
-1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
-1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
-1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
-1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
-1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
-1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
-1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
+1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
+1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
+1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
+1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
+1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
+1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
+1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
+1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
+1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2
explain select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where
@@ -1488,66 +1486,6 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
2 DEPENDENT SUBQUERY t2 ref f2,f3 f2 5 1 Using where
DROP TABLE t1,t2;
-#
-# Generic @@optimizer_switch tests (move those into a separate file if
-# we get another @@optimizer_switch user)
-#
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
-set optimizer_switch='index_merge=off,index_merge_union=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
-set optimizer_switch='index_merge_union=on';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
-set optimizer_switch='default,index_merge_sort_union=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on
-set optimizer_switch=4;
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
-set optimizer_switch=NULL;
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'NULL'
-set optimizer_switch='default,index_merge';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
-set optimizer_switch='index_merge=index_merge';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=index_merge'
-set optimizer_switch='index_merge=on,but...';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'but...'
-set optimizer_switch='index_merge=';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge='
-set optimizer_switch='index_merge';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
-set optimizer_switch='on';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'on'
-set optimizer_switch='index_merge=on,index_merge=off';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off'
-set optimizer_switch='index_merge_union=on,index_merge_union=default';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge_union=default'
-set optimizer_switch='default,index_merge=on,index_merge=off,default';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off,default'
-set optimizer_switch=default;
-set optimizer_switch='index_merge=off,index_merge_union=off,default';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
-set optimizer_switch=default;
-select @@global.optimizer_switch;
-@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
-set @@global.optimizer_switch=default;
-select @@global.optimizer_switch;
-@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
-#
-# Check index_merge's @@optimizer_switch flags
-#
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, c int, filler char(100),
@@ -1655,7 +1593,4 @@ explain select * from t1 where a=10 and b=10 or c=10;
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;
-show 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
drop table t0, t1;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 8a2b258e356..b32e25ef07e 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -324,7 +324,7 @@ information_schema.SCHEMATA b where
a.ROUTINE_SCHEMA = b.SCHEMA_NAME;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE # ALL NULL NULL NULL NULL NULL
-1 SIMPLE # ALL NULL NULL NULL NULL NULL Using where; Using join buffer
+1 SIMPLE # ALL NULL NULL NULL NULL NULL Using where; Using join buffer (flat, BNL join)
select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) AND a.ROUTINE_SCHEMA='test' order by 1;
ROUTINE_NAME name
@@ -1450,7 +1450,7 @@ from information_schema.tables a, information_schema.columns b
where a.table_name='t1' and a.table_schema='test' and b.table_name=a.table_name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Skip_open_table; Scanned 0 databases
-1 SIMPLE b ALL NULL NULL NULL NULL NULL Using where; Open_frm_only; Scanned all databases; Using join buffer
+1 SIMPLE b ALL NULL NULL NULL NULL NULL Using where; Open_frm_only; Scanned all databases; Using join buffer (flat, BNL join)
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'mysqltest';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 718e363adb7..ea0972a6a43 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1295,7 +1295,7 @@ count(*)
623
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using where
+1 SIMPLE t1 range c c 5 NULL # Using index condition; Using MRR
update t1 set c=a;
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
@@ -1990,7 +1990,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -2166,7 +2166,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using where
+1 SIMPLE t1 ref v v 303 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result
new file mode 100644
index 00000000000..76a0e0516b2
--- /dev/null
+++ b/mysql-test/r/innodb_mrr.result
@@ -0,0 +1,662 @@
+drop table if exists t1,t2,t3,t4;
+set @save_storage_engine= @@storage_engine;
+set storage_engine=InnoDB;
+create table t1(a int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+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 + 10*C.a) from t1 A, t1 B, t1 C;
+create table t3 (
+a char(8) not null, b char(8) not null, filler char(200),
+key(a)
+);
+insert into t3 select @a:=concat('c-', 1000+ A.a, '=w'), @a, 'filler' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 2000+A.a, '=w'),
+'filler-1' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 3000+A.a, '=w'),
+'filler-2' from t2 A;
+select a,filler from t3 where a >= 'c-9011=w';
+a filler
+select a,filler from t3 where a >= 'c-1011=w' and a <= 'c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+(a>='c-1014=w' and a <= 'c-1015=w');
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+insert into t3 values ('c-1013=z', 'c-1013=z', 'err');
+insert into t3 values ('a-1014=w', 'a-1014=w', 'err');
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+(a>='c-1014=w' and a <= 'c-1015=w');
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+delete from t3 where b in ('c-1013=z', 'a-1014=w');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+a='c-1014=w' or a='c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+insert into t3 values ('c-1013=w', 'del-me', 'inserted');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+a='c-1014=w' or a='c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+c-1013=w inserted
+delete from t3 where b='del-me';
+alter table t3 add primary key(b);
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+b IN ('c-1019=w', 'c-1020=w', 'c-1021=w',
+'c-1022=w', 'c-1023=w', 'c-1024=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+c-1024=w filler
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1020=w') or
+b IN ('c-1021=w', 'c-1022=w', 'c-1023=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+b IN ('c-1019=w', 'c-1020=w') or
+(b>='c-1021=w' and b<= 'c-1023=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+drop table if exists t4;
+create table t4 (a varchar(10), b int, c char(10), filler char(200),
+key idx1 (a, b, c));
+insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'b-1',NULL,'c-1', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'b-1',NULL,'c-222', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'bb-1',NULL,'cc-2', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'zz-1',NULL,'cc-2', 'filler-data' from t2 order by a limit 500;
+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; Using MRR
+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
+NULL NULL NULL NULL-15
+NULL NULL NULL NULL-14
+NULL NULL NULL NULL-13
+NULL NULL NULL NULL-12
+NULL NULL NULL NULL-11
+NULL NULL NULL NULL-10
+NULL NULL NULL NULL-9
+NULL NULL NULL NULL-8
+NULL NULL NULL NULL-7
+NULL NULL NULL NULL-6
+NULL NULL NULL NULL-5
+NULL NULL NULL NULL-4
+NULL NULL NULL NULL-3
+NULL NULL NULL NULL-2
+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; Using MRR
+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
+b-1 NULL c-1 NULL-14
+b-1 NULL c-1 NULL-13
+b-1 NULL c-1 NULL-12
+b-1 NULL c-1 NULL-11
+b-1 NULL c-1 NULL-10
+b-1 NULL c-1 NULL-9
+b-1 NULL c-1 NULL-8
+b-1 NULL c-1 NULL-7
+b-1 NULL c-1 NULL-6
+b-1 NULL c-1 NULL-5
+b-1 NULL c-1 NULL-4
+b-1 NULL c-1 NULL-3
+b-1 NULL c-1 NULL-2
+b-1 NULL c-1 NULL-1
+bb-1 NULL cc-2 NULL-15
+bb-1 NULL cc-2 NULL-14
+bb-1 NULL cc-2 NULL-13
+bb-1 NULL cc-2 NULL-12
+bb-1 NULL cc-2 NULL-11
+bb-1 NULL cc-2 NULL-10
+bb-1 NULL cc-2 NULL-9
+bb-1 NULL cc-2 NULL-8
+bb-1 NULL cc-2 NULL-7
+bb-1 NULL cc-2 NULL-6
+bb-1 NULL cc-2 NULL-5
+bb-1 NULL cc-2 NULL-4
+bb-1 NULL cc-2 NULL-3
+bb-1 NULL cc-2 NULL-2
+bb-1 NULL cc-2 NULL-1
+select * from t4 ignore index(idx1) 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
+b-1 NULL c-1 NULL-14
+b-1 NULL c-1 NULL-13
+b-1 NULL c-1 NULL-12
+b-1 NULL c-1 NULL-11
+b-1 NULL c-1 NULL-10
+b-1 NULL c-1 NULL-9
+b-1 NULL c-1 NULL-8
+b-1 NULL c-1 NULL-7
+b-1 NULL c-1 NULL-6
+b-1 NULL c-1 NULL-5
+b-1 NULL c-1 NULL-4
+b-1 NULL c-1 NULL-3
+b-1 NULL c-1 NULL-2
+b-1 NULL c-1 NULL-1
+bb-1 NULL cc-2 NULL-15
+bb-1 NULL cc-2 NULL-14
+bb-1 NULL cc-2 NULL-13
+bb-1 NULL cc-2 NULL-12
+bb-1 NULL cc-2 NULL-11
+bb-1 NULL cc-2 NULL-10
+bb-1 NULL cc-2 NULL-9
+bb-1 NULL cc-2 NULL-8
+bb-1 NULL cc-2 NULL-7
+bb-1 NULL cc-2 NULL-6
+bb-1 NULL cc-2 NULL-5
+bb-1 NULL cc-2 NULL-4
+bb-1 NULL cc-2 NULL-3
+bb-1 NULL cc-2 NULL-2
+bb-1 NULL cc-2 NULL-1
+drop table t1, t2, t3, t4;
+create table t1 (a int, b int not null,unique key (a,b),index(b));
+insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6);
+create table t2 like t1;
+insert into t2 select * from t1;
+alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
+select * from t1 where a is null;
+a b c
+NULL 7 0
+NULL 9 0
+NULL 9 0
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
+a b c
+NULL 9 0
+NULL 9 0
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
+a b c
+NULL 7 0
+NULL 9 0
+NULL 9 0
+drop table t1, t2;
+set storage_engine= @save_storage_engine;
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=64;
+Warnings:
+Warning 1292 Truncated incorrect mrr_buffer_size value: '64'
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a char(8), b char(8), c char(8), filler char(100), key(a,b,c) ) engine=InnoDB;
+insert into t2 select
+concat('a-', 1000 + A.a, '-a'),
+concat('b-', 1000 + B.a, '-b'),
+concat('c-', 1000 + C.a, '-c'),
+'filler'
+from t1 A, t1 B, t1 C;
+explain
+select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 9 NULL 99 Using index condition; Using MRR
+select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a';
+count(length(a) + length(filler))
+100
+drop table t2;
+create table t2 (a char(100), b char(100), c char(100), d int,
+filler char(10), key(d), primary key (a,b,c)) engine= innodb;
+insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B;
+explain select * from t2 force index (d) where d < 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range d d 5 NULL # Using index condition; Using MRR
+drop table t2;
+drop table t1;
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+create table t1 (f1 int not null, f2 int not null,f3 int not null, f4 char(1), primary key (f1,f2), key ix(f3))Engine=InnoDB;
+select * from t1 where (f3>=5 and f3<=10) or (f3>=1 and f3<=4);
+f1 f2 f3 f4
+1 1 1 A
+2 2 2 A
+3 3 3 A
+4 4 4 A
+5 5 5 A
+6 6 6 A
+7 7 7 A
+8 8 8 A
+9 9 9 A
+10 10 10 A
+drop table t1;
+
+BUG#37977: Wrong result returned on GROUP BY + OR + Innodb
+
+CREATE TABLE t1 (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+`date_key` date NOT NULL,
+`date_nokey` date NOT NULL,
+`time_key` time NOT NULL,
+`time_nokey` time NOT NULL,
+`datetime_key` datetime NOT NULL,
+`datetime_nokey` datetime NOT NULL,
+`varchar_key` varchar(5) DEFAULT NULL,
+`varchar_nokey` varchar(5) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `date_key` (`date_key`),
+KEY `time_key` (`time_key`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1,5,5,'2009-10-16','2009-10-16','09:28:15','09:28:15','2007-09-14 05:34:08','2007-09-14 05:34:08','qk','qk'),
+(2,6,6,'0000-00-00','0000-00-00','23:06:39','23:06:39','0000-00-00 00:00:00','0000-00-00 00:00:00','j','j'),
+(3,10,10,'2000-12-18','2000-12-18','22:16:19','22:16:19','2006-11-04 15:42:50','2006-11-04 15:42:50','aew','aew'),
+(4,0,0,'2001-09-18','2001-09-18','00:00:00','00:00:00','2004-03-23 13:23:35','2004-03-23 13:23:35',NULL,NULL),
+(5,6,6,'2007-08-16','2007-08-16','22:13:38','22:13:38','2004-08-19 11:01:28','2004-08-19 11:01:28','qu','qu');
+select pk from t1 WHERE `varchar_key` > 'kr' group by pk;
+pk
+1
+5
+select pk from t1 WHERE `int_nokey` IS NULL OR `varchar_key` > 'kr' group by pk;
+pk
+1
+5
+drop table t1;
+#
+# BUG#39447: Error with NOT NULL condition and LIMIT 1
+#
+CREATE TABLE t1 (
+id int(11) NOT NULL,
+parent_id int(11) DEFAULT NULL,
+name varchar(10) DEFAULT NULL,
+PRIMARY KEY (id),
+KEY ind_parent_id (parent_id)
+) ENGINE=InnoDB;
+insert into t1 (id, parent_id, name) values
+(10,NULL,'A'),
+(20,10,'B'),
+(30,10,'C'),
+(40,NULL,'D'),
+(50,40,'E'),
+(60,40,'F'),
+(70,NULL,'J');
+SELECT id FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
+id
+60
+This must show type=index, extra=Using where
+explain SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 1 Using where
+SELECT * FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
+id parent_id name
+60 40 F
+drop table t1;
+#
+# BUG#628785: multi_range_read.cc:430: int DsMrr_impl::dsmrr_init(): Assertion `do_sort_keys || do_rowid_fetch' failed
+#
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_switch= @@optimizer_switch;
+SET SESSION join_cache_level=9;
+Warnings:
+Warning 1292 Truncated incorrect join_cache_level value: '9'
+SET SESSION optimizer_switch='mrr_sort_keys=off';
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,6,NULL,'r','r');
+INSERT INTO `t1` VALUES (2,8,0,'c','c');
+INSERT INTO `t1` VALUES (97,7,0,'z','z');
+INSERT INTO `t1` VALUES (98,1,1,'j','j');
+INSERT INTO `t1` VALUES (99,7,8,'c','c');
+INSERT INTO `t1` VALUES (100,2,5,'f','f');
+SELECT table1 .`col_varchar_key`
+FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ;
+col_varchar_key
+DROP TABLE t1;
+set join_cache_level=@save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
+#
+# BUG#623300: Query with join_cache_level = 6 returns extra rows in maria-5.3-dsmrr-cpk
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_nokey int(11) DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (10,7);
+INSERT INTO t1 VALUES (11,1);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (13,3);
+INSERT INTO t1 VALUES (14,6);
+INSERT INTO t1 VALUES (15,92);
+INSERT INTO t1 VALUES (16,7);
+INSERT INTO t1 VALUES (17,NULL);
+INSERT INTO t1 VALUES (18,3);
+INSERT INTO t1 VALUES (19,5);
+INSERT INTO t1 VALUES (20,1);
+INSERT INTO t1 VALUES (21,2);
+INSERT INTO t1 VALUES (22,NULL);
+INSERT INTO t1 VALUES (23,1);
+INSERT INTO t1 VALUES (24,0);
+INSERT INTO t1 VALUES (25,210);
+INSERT INTO t1 VALUES (26,8);
+INSERT INTO t1 VALUES (27,7);
+INSERT INTO t1 VALUES (28,5);
+INSERT INTO t1 VALUES (29,NULL);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_nokey int(11) DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,NULL);
+INSERT INTO t2 VALUES (2,7);
+INSERT INTO t2 VALUES (3,9);
+INSERT INTO t2 VALUES (4,7);
+INSERT INTO t2 VALUES (5,4);
+INSERT INTO t2 VALUES (6,2);
+INSERT INTO t2 VALUES (7,6);
+INSERT INTO t2 VALUES (8,8);
+INSERT INTO t2 VALUES (9,NULL);
+INSERT INTO t2 VALUES (10,5);
+INSERT INTO t2 VALUES (11,NULL);
+INSERT INTO t2 VALUES (12,6);
+INSERT INTO t2 VALUES (13,188);
+INSERT INTO t2 VALUES (14,2);
+INSERT INTO t2 VALUES (15,1);
+INSERT INTO t2 VALUES (16,1);
+INSERT INTO t2 VALUES (17,0);
+INSERT INTO t2 VALUES (18,9);
+INSERT INTO t2 VALUES (19,NULL);
+INSERT INTO t2 VALUES (20,4);
+set @my_save_join_cache_level= @@join_cache_level;
+SET join_cache_level = 0;
+SELECT table2.col_int_nokey
+FROM t1 table1 JOIN t2 table2 ON table2.pk = table1.col_int_nokey
+WHERE table1.pk ;
+col_int_nokey
+2
+4
+4
+4
+6
+6
+6
+7
+8
+9
+9
+NULL
+NULL
+NULL
+SET join_cache_level = 6;
+SELECT table2.col_int_nokey
+FROM t1 table1 JOIN t2 table2 ON table2.pk = table1.col_int_nokey
+WHERE table1.pk ;
+col_int_nokey
+2
+4
+4
+4
+6
+6
+6
+7
+8
+9
+9
+NULL
+NULL
+NULL
+set join_cache_level= @my_save_join_cache_level;
+drop table t1, t2;
+#
+# BUG#623315: Query returns less rows when run with join_cache_level=6 on maria-5.3-dsmrr-cpk
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_nokey int(11) DEFAULT NULL,
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (10,7,8,'v');
+INSERT INTO t1 VALUES (11,1,9,'r');
+INSERT INTO t1 VALUES (12,5,9,'a');
+INSERT INTO t1 VALUES (13,3,186,'m');
+INSERT INTO t1 VALUES (14,6,NULL,'y');
+INSERT INTO t1 VALUES (15,92,2,'j');
+INSERT INTO t1 VALUES (16,7,3,'d');
+INSERT INTO t1 VALUES (17,NULL,0,'z');
+INSERT INTO t1 VALUES (18,3,133,'e');
+INSERT INTO t1 VALUES (19,5,1,'h');
+INSERT INTO t1 VALUES (20,1,8,'b');
+INSERT INTO t1 VALUES (21,2,5,'s');
+INSERT INTO t1 VALUES (22,NULL,5,'e');
+INSERT INTO t1 VALUES (23,1,8,'j');
+INSERT INTO t1 VALUES (24,0,6,'e');
+INSERT INTO t1 VALUES (25,210,51,'f');
+INSERT INTO t1 VALUES (26,8,4,'v');
+INSERT INTO t1 VALUES (27,7,7,'x');
+INSERT INTO t1 VALUES (28,5,6,'m');
+INSERT INTO t1 VALUES (29,NULL,4,'c');
+set @my_save_join_cache_level= @@join_cache_level;
+SET join_cache_level=6;
+select count(*) from
+(SELECT table2.pk FROM
+t1 LEFT JOIN t1 table2 JOIN t1 table3 ON table3.col_varchar_key = table2.col_varchar_key
+ON table3.col_int_nokey) foo;
+count(*)
+480
+SET join_cache_level=0;
+select count(*) from
+(SELECT table2.pk FROM
+t1 LEFT JOIN t1 table2 JOIN t1 table3 ON table3.col_varchar_key = table2.col_varchar_key
+ON table3.col_int_nokey) foo;
+count(*)
+480
+set join_cache_level= @my_save_join_cache_level;
+drop table t1;
+#
+# BUG#671340: Diverging results in with mrr_sort_keys=ON|OFF and join_cache_level=5
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) NOT NULL,
+col_varchar_key varchar(1) NOT NULL,
+col_varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(10,8,'v','v'),
+(11,8,'f','f'),
+(12,5,'v','v'),
+(13,8,'s','s'),
+(14,8,'a','a'),
+(15,6,'p','p'),
+(16,7,'z','z'),
+(17,2,'a','a'),
+(18,5,'h','h'),
+(19,7,'h','h'),
+(20,2,'v','v'),
+(21,9,'v','v'),
+(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');
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) NOT NULL,
+col_varchar_key varchar(1) NOT NULL,
+col_varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,9,'x','x'),
+(2,5,'g','g'),
+(3,1,'o','o'),
+(4,0,'g','g'),
+(5,1,'v','v'),
+(6,190,'m','m'),
+(7,6,'x','x'),
+(8,3,'c','c'),
+(9,4,'z','z'),
+(10,3,'i','i'),
+(11,186,'x','x'),
+(12,1,'g','g'),
+(13,8,'q','q'),
+(14,226,'m','m'),
+(15,133,'p','p'),
+(16,6,'e','e'),
+(17,3,'t','t'),
+(18,8,'j','j'),
+(19,5,'h','h'),
+(20,7,'w','w');
+SELECT count(*), sum(table1.col_int_key*table2.pk)
+FROM
+t2 AS table1, t1 AS table2, t2 AS table3
+WHERE
+table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
+count(*) sum(table1.col_int_key*table2.pk)
+240 185955
+set @my_save_join_cache_level= @@join_cache_level;
+set @my_save_join_buffer_size= @@join_buffer_size;
+set join_cache_level=6;
+set join_buffer_size=1500;
+SELECT count(*), sum(table1.col_int_key*table2.pk)
+FROM
+t2 AS table1, t1 AS table2, t2 AS table3
+WHERE
+table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
+count(*) sum(table1.col_int_key*table2.pk)
+240 185955
+drop table t1,t2;
+set join_cache_level=@my_save_join_cache_level;
+set join_buffer_size=@my_save_join_buffer_size;
diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result
new file mode 100644
index 00000000000..b7824b45862
--- /dev/null
+++ b/mysql-test/r/innodb_mrr_cpk.result
@@ -0,0 +1,148 @@
+drop table if exists t0,t1,t2,t3;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+set @save_storage_engine=@@storage_engine;
+set storage_engine=innodb;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a char(8), b char(8), filler char(100), primary key(a));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(8) NOT NULL DEFAULT '',
+ `b` char(8) DEFAULT NULL,
+ `filler` char(100) DEFAULT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 select
+concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'),
+concat('b-', 1000 + A.a + B.a*10 + C.a*100, '=B'),
+'filler'
+from t0 A, t0 B, t0 C;
+create table t2 (a char(8));
+insert into t2 values ('a-1010=A'), ('a-1030=A'), ('a-1020=A');
+This should use join buffer:
+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 NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 8 test.t2.a 1 Using join buffer (flat, BKA join)
+This output must be sorted by value of t1.a:
+select * from t1, t2 where t1.a=t2.a;
+a b filler a
+a-1010=A b-1010=B filler a-1010=A
+a-1020=A b-1020=B filler a-1020=A
+a-1030=A b-1030=B filler a-1030=A
+drop table t1, t2;
+create table t1(
+a char(8) character set utf8, b int, filler char(100),
+primary key(a,b)
+);
+insert into t1 select
+concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'),
+1000 + A.a + B.a*10 + C.a*100,
+'filler'
+from t0 A, t0 B, t0 C;
+create table t2 (a char(8) character set utf8, b int);
+insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 28 test.t2.a,test.t2.b 1 Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+a b filler a b
+a-1010=A 1010 filler a-1010=A 1010
+a-1020=A 1020 filler a-1020=A 1020
+a-1030=A 1030 filler a-1030=A 1030
+insert into t2 values ('a-1030=A', 1030), ('a-1020=A', 1020);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 28 test.t2.a,test.t2.b 1 Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+a b filler a b
+a-1010=A 1010 filler a-1010=A 1010
+a-1020=A 1020 filler a-1020=A 1020
+a-1020=A 1020 filler a-1020=A 1020
+a-1030=A 1030 filler a-1030=A 1030
+a-1030=A 1030 filler a-1030=A 1030
+drop table t1, t2;
+create table t1(
+a varchar(8) character set utf8, b int, filler char(100),
+primary key(a,b)
+);
+insert into t1 select
+concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'),
+1000 + A.a + B.a*10 + C.a*100,
+'filler'
+from t0 A, t0 B, t0 C;
+create table t2 (a char(8) character set utf8, b int);
+insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using index condition(BKA); Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+a b filler a b
+a-1010=A 1010 filler a-1010=A 1010
+a-1020=A 1020 filler a-1020=A 1020
+a-1030=A 1030 filler a-1030=A 1030
+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 NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a;
+a b filler a b
+a-1010=A 1010 filler a-1010=A 1010
+a-1020=A 1020 filler a-1020=A 1020
+a-1030=A 1030 filler a-1030=A 1030
+drop table t1, t2;
+create table t1 (a int, b int, c int, filler char(100), primary key(a,b,c));
+insert into t1 select A.a, B.a, C.a, 'filler' from t0 A, t0 B, t0 C;
+insert into t1 values (11, 11, 11, 'filler');
+insert into t1 values (11, 11, 12, 'filler');
+insert into t1 values (11, 11, 13, 'filler');
+insert into t1 values (11, 22, 1234, 'filler');
+insert into t1 values (11, 33, 124, 'filler');
+insert into t1 values (11, 33, 125, 'filler');
+create table t2 (a int, b int);
+insert into t2 values (11,33), (11,22), (11,11);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 ref PRIMARY PRIMARY 8 test.t2.a,test.t2.b 1 Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+a b c filler a b
+11 11 11 filler 11 11
+11 11 12 filler 11 11
+11 11 13 filler 11 11
+11 22 1234 filler 11 22
+11 33 124 filler 11 33
+11 33 125 filler 11 33
+set join_cache_level=0;
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+a b c filler a b
+11 33 124 filler 11 33
+11 33 125 filler 11 33
+11 22 1234 filler 11 22
+11 11 11 filler 11 11
+11 11 12 filler 11 11
+11 11 13 filler 11 11
+set join_cache_level=6;
+explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+a b c filler a b
+set optimizer_switch='index_condition_pushdown=off';
+explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
+select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+a b c filler a b
+set optimizer_switch='index_condition_pushdown=on';
+drop table t1,t2;
+set @@join_cache_level= @save_join_cache_level;
+set storage_engine=@save_storage_engine;
+drop table t0;
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 96504df4b1e..e8df0cfec2f 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -404,7 +404,7 @@ SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
ORDER BY t1.b, t1.c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort
-1 SIMPLE t2 ALL NULL NULL NULL NULL 16 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
ORDER BY t1.b, t1.c;
e
@@ -846,7 +846,7 @@ select * from t1, t2, t3 where t3.a=t1.a and t2.a=t1.b;
a b a a
explain select * from t1, t2, t3 where t3.a=t1.a and t2.a=t1.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using index
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
We expect rnd_next=5, and read_key must be 0 because of short-cutting:
@@ -869,7 +869,7 @@ insert into t3 select * from t2 where a < 800;
explain select * from t2,t3 where t2.a < 200 and t2.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a,b NULL NULL NULL 1000 Using where
-1 SIMPLE t3 ref b b 5 test.t2.b 1 Using where
+1 SIMPLE t3 ref b b 5 test.t2.b 1
drop table t1, t2, t3;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -889,8 +889,8 @@ Z
vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv
explain select * from t1, t2 A, t2 B where A.a = t1.a and B.a=A.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 10
-1 SIMPLE A eq_ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
+1 SIMPLE A eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
1 SIMPLE B eq_ref PRIMARY PRIMARY 4 test.A.b 1
show status like '%cost%';
Variable_name Value
@@ -910,7 +910,7 @@ INSERT INTO t1 SELECT a + 64, b FROM t1;
INSERT INTO t2 SELECT a, b FROM t1;
EXPLAIN SELECT * FROM t1 JOIN t2 ON b=c ORDER BY a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index NULL PRIMARY 4 NULL 2
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1
EXPLAIN SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
@@ -924,7 +924,7 @@ a b c d
2 NULL 2 NULL
EXPLAIN SELECT * FROM t1 JOIN t2 ON b=c ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort
+1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using where; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1
EXPLAIN SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
@@ -1095,11 +1095,11 @@ ON t4.a = t5.a
ON t1.a = t3.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t3 ref a a 5 test.t1.a 2 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 0
-1 SIMPLE t5 ALL NULL NULL NULL NULL 0
-1 SIMPLE t6 ALL NULL NULL NULL NULL 0
-1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
+1 SIMPLE t3 ref a a 5 test.t1.a 2 Using where; Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 0 Using where
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
SELECT *
FROM
t1 JOIN t2 ON t1.a = t2.a
@@ -1127,9 +1127,9 @@ EXPLAIN EXTENDED
SELECT 1 FROM v1 right join v1 AS v2 ON RAND();
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
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` left join `test`.`t1` `t2` on((1 = 1)) left join (`test`.`t1` left join `test`.`t1` `t2` on((1 = 1))) on(rand()) where 1
DROP VIEW v1;
@@ -1220,4 +1220,34 @@ f1
2
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+#
+# BUG#47217 Lost optimization caused slowdown & wrong result.
+#
+CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
+CREATE INDEX ix1 ON t1(v);
+CREATE TABLE t2 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
+CREATE INDEX ix2 ON t2(v);
+INSERT INTO t1 VALUES (1,'a'),(2,NULL);
+INSERT INTO t2 VALUES (1,NULL);
+EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v ORDER BY 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+INSERT INTO t1 VALUES (3,'b'),(4,NULL),(5,'c'),(6,'cc'),(7,'d'),
+(8,'dd'),(9,'e'),(10,'ee');
+INSERT INTO t2 VALUES (2,NULL);
+FLUSH STATUS;
+SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1;
+pk v pk v
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 1
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 1
+DROP TABLE t1, t2;
End of 5.1 tests
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
new file mode 100644
index 00000000000..bbe326d7b19
--- /dev/null
+++ b/mysql-test/r/join_cache.result
@@ -0,0 +1,6125 @@
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
+DROP DATABASE IF EXISTS world;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL
+);
+CREATE TABLE City (
+ID int(11) NOT NULL,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0'
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0'
+);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 131072
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+set join_cache_level=2;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 2
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+set join_cache_level=default;
+set join_buffer_size=256;
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 256
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+set join_cache_level=2;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 2
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+set join_cache_level=default;
+set join_buffer_size=default;
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 131072
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+DROP DATABASE world;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 131072
+set join_cache_level=3;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 3
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition; Using where
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BNLH join)
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+Name IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+Australia 81.2
+United Kingdom 97.3
+Canada 60.4
+United States 86.2
+Zimbabwe 2.2
+Japan 0.1
+South Africa 8.5
+Malaysia 1.6
+Afghanistan NULL
+Netherlands NULL
+Algeria NULL
+Angola NULL
+Argentina NULL
+Bangladesh NULL
+Belgium NULL
+Brazil NULL
+Burkina Faso NULL
+Chile NULL
+Ecuador NULL
+Egypt NULL
+Spain NULL
+Ethiopia NULL
+Philippines NULL
+Ghana NULL
+Guatemala NULL
+Indonesia NULL
+India NULL
+Iraq NULL
+Iran NULL
+Italy NULL
+Yemen NULL
+Yugoslavia NULL
+Cambodia NULL
+Cameroon NULL
+Kazakstan NULL
+Kenya NULL
+China NULL
+Colombia NULL
+Congo, The Democratic Republic of the NULL
+North Korea NULL
+South Korea NULL
+Greece NULL
+Cuba NULL
+Madagascar NULL
+Malawi NULL
+Mali NULL
+Morocco NULL
+Mexico NULL
+Mozambique NULL
+Myanmar NULL
+Nepal NULL
+Niger NULL
+Nigeria NULL
+Côte d?Ivoire NULL
+Pakistan NULL
+Peru NULL
+Poland NULL
+France NULL
+Romania NULL
+Germany NULL
+Saudi Arabia NULL
+Somalia NULL
+Sri Lanka NULL
+Sudan NULL
+Syria NULL
+Taiwan NULL
+Tanzania NULL
+Thailand NULL
+Czech Republic NULL
+Turkey NULL
+Uganda NULL
+Ukraine NULL
+Hungary NULL
+Uzbekistan NULL
+Belarus NULL
+Venezuela NULL
+Russian Federation NULL
+Vietnam NULL
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 131072
+set join_cache_level=4;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 4
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer (incremental, BNLH join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BNLH join)
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+Name IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+Australia 81.2
+United Kingdom 97.3
+Canada 60.4
+United States 86.2
+Zimbabwe 2.2
+Japan 0.1
+South Africa 8.5
+Malaysia 1.6
+Afghanistan NULL
+Netherlands NULL
+Algeria NULL
+Angola NULL
+Argentina NULL
+Bangladesh NULL
+Belgium NULL
+Brazil NULL
+Burkina Faso NULL
+Chile NULL
+Ecuador NULL
+Egypt NULL
+Spain NULL
+Ethiopia NULL
+Philippines NULL
+Ghana NULL
+Guatemala NULL
+Indonesia NULL
+India NULL
+Iraq NULL
+Iran NULL
+Italy NULL
+Yemen NULL
+Yugoslavia NULL
+Cambodia NULL
+Cameroon NULL
+Kazakstan NULL
+Kenya NULL
+China NULL
+Colombia NULL
+Congo, The Democratic Republic of the NULL
+North Korea NULL
+South Korea NULL
+Greece NULL
+Cuba NULL
+Madagascar NULL
+Malawi NULL
+Mali NULL
+Morocco NULL
+Mexico NULL
+Mozambique NULL
+Myanmar NULL
+Nepal NULL
+Niger NULL
+Nigeria NULL
+Côte d?Ivoire NULL
+Pakistan NULL
+Peru NULL
+Poland NULL
+France NULL
+Romania NULL
+Germany NULL
+Saudi Arabia NULL
+Somalia NULL
+Sri Lanka NULL
+Sudan NULL
+Syria NULL
+Taiwan NULL
+Tanzania NULL
+Thailand NULL
+Czech Republic NULL
+Turkey NULL
+Uganda NULL
+Ukraine NULL
+Hungary NULL
+Uzbekistan NULL
+Belarus NULL
+Venezuela NULL
+Russian Federation NULL
+Vietnam NULL
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 131072
+set join_cache_level=5;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 5
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKA join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKA join)
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+Name IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+Australia 81.2
+United Kingdom 97.3
+Canada 60.4
+United States 86.2
+Zimbabwe 2.2
+Japan 0.1
+South Africa 8.5
+Malaysia 1.6
+Afghanistan NULL
+Netherlands NULL
+Algeria NULL
+Angola NULL
+Argentina NULL
+Bangladesh NULL
+Belgium NULL
+Brazil NULL
+Burkina Faso NULL
+Chile NULL
+Ecuador NULL
+Egypt NULL
+Spain NULL
+Ethiopia NULL
+Philippines NULL
+Ghana NULL
+Guatemala NULL
+Indonesia NULL
+India NULL
+Iraq NULL
+Iran NULL
+Italy NULL
+Yemen NULL
+Yugoslavia NULL
+Cambodia NULL
+Cameroon NULL
+Kazakstan NULL
+Kenya NULL
+China NULL
+Colombia NULL
+Congo, The Democratic Republic of the NULL
+North Korea NULL
+South Korea NULL
+Greece NULL
+Cuba NULL
+Madagascar NULL
+Malawi NULL
+Mali NULL
+Morocco NULL
+Mexico NULL
+Mozambique NULL
+Myanmar NULL
+Nepal NULL
+Niger NULL
+Nigeria NULL
+Côte d?Ivoire NULL
+Pakistan NULL
+Peru NULL
+Poland NULL
+France NULL
+Romania NULL
+Germany NULL
+Saudi Arabia NULL
+Somalia NULL
+Sri Lanka NULL
+Sudan NULL
+Syria NULL
+Taiwan NULL
+Tanzania NULL
+Thailand NULL
+Czech Republic NULL
+Turkey NULL
+Uganda NULL
+Ukraine NULL
+Hungary NULL
+Uzbekistan NULL
+Belarus NULL
+Venezuela NULL
+Russian Federation NULL
+Vietnam NULL
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKA join)
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+Name IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+Australia 81.2
+United Kingdom 97.3
+Canada 60.4
+United States 86.2
+Zimbabwe 2.2
+Japan 0.1
+South Africa 8.5
+Malaysia 1.6
+Afghanistan NULL
+Netherlands NULL
+Algeria NULL
+Angola NULL
+Argentina NULL
+Bangladesh NULL
+Belgium NULL
+Brazil NULL
+Burkina Faso NULL
+Chile NULL
+Ecuador NULL
+Egypt NULL
+Spain NULL
+Ethiopia NULL
+Philippines NULL
+Ghana NULL
+Guatemala NULL
+Indonesia NULL
+India NULL
+Iraq NULL
+Iran NULL
+Italy NULL
+Yemen NULL
+Yugoslavia NULL
+Cambodia NULL
+Cameroon NULL
+Kazakstan NULL
+Kenya NULL
+China NULL
+Colombia NULL
+Congo, The Democratic Republic of the NULL
+North Korea NULL
+South Korea NULL
+Greece NULL
+Cuba NULL
+Madagascar NULL
+Malawi NULL
+Mali NULL
+Morocco NULL
+Mexico NULL
+Mozambique NULL
+Myanmar NULL
+Nepal NULL
+Niger NULL
+Nigeria NULL
+Côte d?Ivoire NULL
+Pakistan NULL
+Peru NULL
+Poland NULL
+France NULL
+Romania NULL
+Germany NULL
+Saudi Arabia NULL
+Somalia NULL
+Sri Lanka NULL
+Sudan NULL
+Syria NULL
+Taiwan NULL
+Tanzania NULL
+Thailand NULL
+Czech Republic NULL
+Turkey NULL
+Uganda NULL
+Ukraine NULL
+Hungary NULL
+Uzbekistan NULL
+Belarus NULL
+Venezuela NULL
+Russian Federation NULL
+Vietnam NULL
+set join_cache_level=7;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 7
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKAH join)
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+Name IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+Australia 81.2
+United Kingdom 97.3
+Canada 60.4
+United States 86.2
+Zimbabwe 2.2
+Japan 0.1
+South Africa 8.5
+Malaysia 1.6
+Afghanistan NULL
+Netherlands NULL
+Algeria NULL
+Angola NULL
+Argentina NULL
+Bangladesh NULL
+Belgium NULL
+Brazil NULL
+Burkina Faso NULL
+Chile NULL
+Ecuador NULL
+Egypt NULL
+Spain NULL
+Ethiopia NULL
+Philippines NULL
+Ghana NULL
+Guatemala NULL
+Indonesia NULL
+India NULL
+Iraq NULL
+Iran NULL
+Italy NULL
+Yemen NULL
+Yugoslavia NULL
+Cambodia NULL
+Cameroon NULL
+Kazakstan NULL
+Kenya NULL
+China NULL
+Colombia NULL
+Congo, The Democratic Republic of the NULL
+North Korea NULL
+South Korea NULL
+Greece NULL
+Cuba NULL
+Madagascar NULL
+Malawi NULL
+Mali NULL
+Morocco NULL
+Mexico NULL
+Mozambique NULL
+Myanmar NULL
+Nepal NULL
+Niger NULL
+Nigeria NULL
+Côte d?Ivoire NULL
+Pakistan NULL
+Peru NULL
+Poland NULL
+France NULL
+Romania NULL
+Germany NULL
+Saudi Arabia NULL
+Somalia NULL
+Sri Lanka NULL
+Sudan NULL
+Syria NULL
+Taiwan NULL
+Tanzania NULL
+Thailand NULL
+Czech Republic NULL
+Turkey NULL
+Uganda NULL
+Ukraine NULL
+Hungary NULL
+Uzbekistan NULL
+Belarus NULL
+Venezuela NULL
+Russian Federation NULL
+Vietnam NULL
+set join_cache_level=8;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 8
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKAH join)
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+FROM Country LEFT JOIN CountryLanguage ON
+(CountryLanguage.Country=Country.Code AND Language='English')
+WHERE
+Country.Population > 10000000;
+Name IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+Australia 81.2
+United Kingdom 97.3
+Canada 60.4
+United States 86.2
+Zimbabwe 2.2
+Japan 0.1
+South Africa 8.5
+Malaysia 1.6
+Afghanistan NULL
+Netherlands NULL
+Algeria NULL
+Angola NULL
+Argentina NULL
+Bangladesh NULL
+Belgium NULL
+Brazil NULL
+Burkina Faso NULL
+Chile NULL
+Ecuador NULL
+Egypt NULL
+Spain NULL
+Ethiopia NULL
+Philippines NULL
+Ghana NULL
+Guatemala NULL
+Indonesia NULL
+India NULL
+Iraq NULL
+Iran NULL
+Italy NULL
+Yemen NULL
+Yugoslavia NULL
+Cambodia NULL
+Cameroon NULL
+Kazakstan NULL
+Kenya NULL
+China NULL
+Colombia NULL
+Congo, The Democratic Republic of the NULL
+North Korea NULL
+South Korea NULL
+Greece NULL
+Cuba NULL
+Madagascar NULL
+Malawi NULL
+Mali NULL
+Morocco NULL
+Mexico NULL
+Mozambique NULL
+Myanmar NULL
+Nepal NULL
+Niger NULL
+Nigeria NULL
+Côte d?Ivoire NULL
+Pakistan NULL
+Peru NULL
+Poland NULL
+France NULL
+Romania NULL
+Germany NULL
+Saudi Arabia NULL
+Somalia NULL
+Sri Lanka NULL
+Sudan NULL
+Syria NULL
+Taiwan NULL
+Tanzania NULL
+Thailand NULL
+Czech Republic NULL
+Turkey NULL
+Uganda NULL
+Ukraine NULL
+Hungary NULL
+Uzbekistan NULL
+Belarus NULL
+Venezuela NULL
+Russian Federation NULL
+Vietnam NULL
+set join_buffer_size=256;
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 256
+set join_cache_level=3;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 3
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition; Using where
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+set join_cache_level=4;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 4
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer (incremental, BNLH join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+set join_cache_level=5;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 5
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKA join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+set join_cache_level=7;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 7
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+set join_cache_level=8;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 8
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
+1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join)
+SELECT City.Name, Country.Name, CountryLanguage.Language
+FROM City,Country,CountryLanguage
+WHERE City.Country=Country.Code AND
+CountryLanguage.Country=Country.Code AND
+City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+CountryLanguage.Percentage > 50;
+Name Name Language
+Leiden Netherlands Dutch
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+La Plata Argentina Spanish
+Lanús Argentina Spanish
+Las Heras Argentina Spanish
+La Rioja Argentina Spanish
+Liège Belgium Dutch
+La Paz Bolivia Spanish
+Londrina Brazil Portuguese
+Limeira Brazil Portuguese
+Lages Brazil Portuguese
+Luziânia Brazil Portuguese
+Lauro de Freitas Brazil Portuguese
+Linhares Brazil Portuguese
+London United Kingdom English
+Liverpool United Kingdom English
+Leeds United Kingdom English
+Leicester United Kingdom English
+Luton United Kingdom English
+Los Angeles Chile Spanish
+La Serena Chile Spanish
+La Romana Dominican Republic Spanish
+Loja Ecuador Spanish
+Luxor Egypt Arabic
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Leganés Spain Spanish
+León Spain Spanish
+Logroño Spain Spanish
+Lleida (Lérida) Spain Spanish
+Le-Cap-Haïtien Haiti Haiti Creole
+La Ceiba Honduras Spanish
+Livorno Italy Italian
+Latina Italy Italian
+Lecce Italy Italian
+La Spezia Italy Italian
+Linz Austria German
+London Canada English
+Laval Canada English
+Longueuil Canada English
+Lanzhou China Chinese
+Luoyang China Chinese
+Liuzhou China Chinese
+Liaoyang China Chinese
+Liupanshui China Chinese
+Liaoyuan China Chinese
+Lianyungang China Chinese
+Leshan China Chinese
+Linyi China Chinese
+Luzhou China Chinese
+Laiwu China Chinese
+Liaocheng China Chinese
+Laizhou China Chinese
+Linfen China Chinese
+Liangcheng China Chinese
+Longkou China Chinese
+Langfang China Chinese
+Liu´an China Chinese
+Longjing China Chinese
+Lengshuijiang China Chinese
+Laiyang China Chinese
+Longyan China Chinese
+Linhe China Chinese
+Leiyang China Chinese
+Loudi China Chinese
+Luohe China Chinese
+Linqing China Chinese
+Laohekou China Chinese
+Linchuan China Chinese
+Lhasa China Chinese
+Lianyuan China Chinese
+Liyang China Chinese
+Liling China Chinese
+Linhai China Chinese
+Larisa Greece Greek
+La Habana Cuba Spanish
+Lilongwe Malawi Chichewa
+León Mexico Spanish
+La Paz Mexico Spanish
+La Paz Mexico Spanish
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Lerdo Mexico Spanish
+Los Cabos Mexico Spanish
+Lerma Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+León Nicaragua Spanish
+Lambaré Paraguay Spanish
+Lima Peru Spanish
+Lisboa Portugal Portuguese
+Lódz Poland Polish
+Lublin Poland Polish
+Legnica Poland Polish
+Lyon France French
+Le Havre France French
+Lille France French
+Le Mans France French
+Limoges France French
+Linköping Sweden Swedish
+Lund Sweden Swedish
+Leipzig Germany German
+Lübeck Germany German
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Lünen Germany German
+Lahti Finland Finnish
+Lausanne Switzerland German
+Latakia Syria Arabic
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Liberec Czech Republic Czech
+Lviv Ukraine Ukrainian
+Lugansk Ukraine Ukrainian
+Lutsk Ukraine Ukrainian
+Lysyt?ansk Ukraine Ukrainian
+Lower Hutt New Zealand English
+Lida Belarus Belorussian
+Los Teques Venezuela Spanish
+Lipetsk Russian Federation Russian
+Ljubertsy Russian Federation Russian
+Leninsk-Kuznetski Russian Federation Russian
+Long Xuyen Vietnam Vietnamese
+Los Angeles United States English
+Las Vegas United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Lincoln United States English
+Lubbock United States English
+Little Rock United States English
+Laredo United States English
+Lakewood United States English
+Lansing United States English
+Lancaster United States English
+Lafayette United States English
+Lowell United States English
+Livonia United States English
+EXPLAIN
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
+SELECT Name FROM City
+WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+City.Population > 100000;
+Name
+Vientiane
+Riga
+Daugavpils
+Maseru
+Beirut
+Tripoli
+Monrovia
+Tripoli
+Bengasi
+Misrata
+Vilnius
+Kaunas
+Klaipeda
+?iauliai
+Panevezys
+set join_cache_level=default;
+set join_buffer_size=default;
+show variables like 'join_buffer_size';
+Variable_name Value
+join_buffer_size 131072
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set join_cache_level=1;
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND City.Population > 3000000;
+Name Name
+Sydney Australia
+Dhaka Bangladesh
+São Paulo Brazil
+Rio de Janeiro Brazil
+London United Kingdom
+Santiago de Chile Chile
+Cairo Egypt
+Alexandria Egypt
+Jakarta Indonesia
+Mumbai (Bombay) India
+Delhi India
+Calcutta [Kolkata] India
+Chennai (Madras) India
+Baghdad Iraq
+Teheran Iran
+Tokyo Japan
+Jokohama [Yokohama] Japan
+Shanghai China
+Peking China
+Chongqing China
+Tianjin China
+Wuhan China
+Harbin China
+Shenyang China
+Kanton [Guangzhou] China
+Chengdu China
+Santafé de Bogotá Colombia
+Kinshasa Congo, The Democratic Republic of the
+Seoul South Korea
+Pusan South Korea
+Ciudad de México Mexico
+Rangoon (Yangon) Myanmar
+Karachi Pakistan
+Lahore Pakistan
+Lima Peru
+Berlin Germany
+Riyadh Saudi Arabia
+Singapore Singapore
+Bangkok Thailand
+Istanbul Turkey
+Ankara Turkey
+Moscow Russian Federation
+St Petersburg Russian Federation
+Ho Chi Minh City Vietnam
+New York United States
+Los Angeles United States
+set join_cache_level=8;
+set join_buffer_size=384;
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND City.Population > 3000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country Population 4 NULL # Using index condition; Using MRR
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country # Using join buffer (flat, BKAH join)
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND City.Population > 3000000;
+Name Name
+Alexandria Egypt
+Ankara Turkey
+Baghdad Iraq
+Bangkok Thailand
+Berlin Germany
+Cairo Egypt
+Calcutta [Kolkata] India
+Chengdu China
+Chennai (Madras) India
+Chongqing China
+Ciudad de México Mexico
+Delhi India
+Dhaka Bangladesh
+Harbin China
+Ho Chi Minh City Vietnam
+Istanbul Turkey
+Jakarta Indonesia
+Jokohama [Yokohama] Japan
+Kanton [Guangzhou] China
+Karachi Pakistan
+Kinshasa Congo, The Democratic Republic of the
+Lahore Pakistan
+Lima Peru
+London United Kingdom
+Los Angeles United States
+Moscow Russian Federation
+Mumbai (Bombay) India
+New York United States
+Peking China
+Pusan South Korea
+Rangoon (Yangon) Myanmar
+Rio de Janeiro Brazil
+Riyadh Saudi Arabia
+Santafé de Bogotá Colombia
+Santiago de Chile Chile
+Seoul South Korea
+Shanghai China
+Shenyang China
+Singapore Singapore
+St Petersburg Russian Federation
+Sydney Australia
+São Paulo Brazil
+Teheran Iran
+Tianjin China
+Tokyo Japan
+Wuhan China
+set join_buffer_size=default;
+set join_cache_level=6;
+ALTER TABLE Country MODIFY Name varchar(52) NOT NULL default '';
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+ALTER TABLE Country MODIFY Name varchar(300) NOT NULL default '';
+SELECT City.Name, Country.Name FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name
+Vientiane Laos
+Riga Latvia
+Daugavpils Latvia
+Maseru Lesotho
+Beirut Lebanon
+Tripoli Lebanon
+Monrovia Liberia
+Tripoli Libyan Arab Jamahiriya
+Bengasi Libyan Arab Jamahiriya
+Misrata Libyan Arab Jamahiriya
+Vilnius Lithuania
+Kaunas Lithuania
+Klaipeda Lithuania
+?iauliai Lithuania
+Panevezys Lithuania
+ALTER TABLE Country ADD COLUMN PopulationBar text;
+UPDATE Country
+SET PopulationBar=REPEAT('x', CAST(Population/100000 AS unsigned int));
+SELECT City.Name, Country.Name, Country.PopulationBar FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name PopulationBar
+Vientiane Laos xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Riga Latvia xxxxxxxxxxxxxxxxxxxxxxxx
+Daugavpils Latvia xxxxxxxxxxxxxxxxxxxxxxxx
+Maseru Lesotho xxxxxxxxxxxxxxxxxxxxxx
+Beirut Lebanon xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Tripoli Lebanon xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Monrovia Liberia xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Tripoli Libyan Arab Jamahiriya xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Bengasi Libyan Arab Jamahiriya xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Misrata Libyan Arab Jamahiriya xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Vilnius Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Kaunas Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Klaipeda Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+?iauliai Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Panevezys Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+set join_buffer_size=256;
+SELECT City.Name, Country.Name, Country.PopulationBar FROM City,Country
+WHERE City.Country=Country.Code AND
+Country.Name LIKE 'L%' AND City.Population > 100000;
+Name Name PopulationBar
+Vientiane Laos xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Riga Latvia xxxxxxxxxxxxxxxxxxxxxxxx
+Daugavpils Latvia xxxxxxxxxxxxxxxxxxxxxxxx
+Maseru Lesotho xxxxxxxxxxxxxxxxxxxxxx
+Beirut Lebanon xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Tripoli Lebanon xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Monrovia Liberia xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Tripoli Libyan Arab Jamahiriya xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Bengasi Libyan Arab Jamahiriya xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Misrata Libyan Arab Jamahiriya xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Vilnius Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Kaunas Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Klaipeda Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+?iauliai Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Panevezys Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+set join_cache_level=default;
+set join_buffer_size=default;
+DROP DATABASE world;
+use test;
+CREATE TABLE t1(
+affiliatetometaid int NOT NULL default '0',
+uniquekey int NOT NULL default '0',
+metaid int NOT NULL default '0',
+affiliateid int NOT NULL default '0',
+xml text,
+isactive char(1) NOT NULL default 'Y',
+PRIMARY KEY (affiliatetometaid)
+);
+CREATE UNIQUE INDEX t1_uniquekey ON t1(uniquekey);
+CREATE INDEX t1_affiliateid ON t1(affiliateid);
+CREATE INDEX t1_metaid on t1 (metaid);
+INSERT INTO t1 VALUES
+(1616, 1571693233, 1391, 2, NULL, 'Y'), (1943, 1993216749, 1726, 2, NULL, 'Y');
+CREATE TABLE t2(
+metaid int NOT NULL default '0',
+name varchar(80) NOT NULL default '',
+dateadded timestamp NOT NULL ,
+xml text,
+status int default NULL,
+origin int default NULL,
+gid int NOT NULL default '1',
+formattypeid int default NULL,
+PRIMARY KEY (metaid)
+);
+CREATE INDEX t2_status ON t2(status);
+CREATE INDEX t2_gid ON t2(gid);
+CREATE INDEX t2_formattypeid ON t2(formattypeid);
+INSERT INTO t2 VALUES
+(1391, "I Just Died", "2003-10-02 10:07:37", "", 1, NULL, 3, NULL),
+(1726, "Me, Myself & I", "2003-12-05 11:24:36", " ", 1, NULL, 3, NULL);
+CREATE TABLE t3(
+mediaid int NOT NULL ,
+metaid int NOT NULL default '0',
+formatid int NOT NULL default '0',
+status int default NULL,
+path varchar(100) NOT NULL default '',
+datemodified timestamp NOT NULL ,
+resourcetype int NOT NULL default '1',
+parameters text,
+signature int default NULL,
+quality int NOT NULL default '255',
+PRIMARY KEY (mediaid)
+);
+CREATE INDEX t3_metaid ON t3(metaid);
+CREATE INDEX t3_formatid ON t3(formatid);
+CREATE INDEX t3_status ON t3(status);
+CREATE INDEX t3_metaidformatid ON t3(metaid,formatid);
+CREATE INDEX t3_signature ON t3(signature);
+CREATE INDEX t3_quality ON t3(quality);
+INSERT INTO t3 VALUES
+(6, 4, 8, 0, "010101_anastacia_spmidi.mid", "2004-03-16 13:40:00", 1, NULL, NULL, 255),
+(3343, 3, 8, 1, "010102_4VN4bsPwnxRQUJW5Zp1RhG2IL9vvl_8.mid", "2004-03-16 13:40:00", 1, NULL, NULL, 255);
+CREATE TABLE t4(
+formatid int NOT NULL ,
+name varchar(60) NOT NULL default '',
+formatclassid int NOT NULL default '0',
+mime varchar(60) default NULL,
+extension varchar(10) default NULL,
+priority int NOT NULL default '0',
+canaddtocapability char(1) NOT NULL default 'Y',
+PRIMARY KEY (formatid)
+);
+CREATE INDEX t4_formatclassid ON t4(formatclassid);
+CREATE INDEX t4_formats_idx ON t4(canaddtocapability);
+INSERT INTO t4 VALUES
+(19, "XHTML", 11, "text/html", "xhtml", 10, 'Y'),
+(54, "AMR (wide band)", 13, "audio/amr-wb", "awb", 0, 'Y');
+CREATE TABLE t5(
+formatclassid int NOT NULL ,
+name varchar(60) NOT NULL default '',
+priority int NOT NULL default '0',
+formattypeid int NOT NULL default '0',
+PRIMARY KEY (formatclassid)
+);
+CREATE INDEX t5_formattypeid on t5(formattypeid);
+INSERT INTO t5 VALUES
+(11, "Info", 0, 4), (13, "Digital Audio", 0, 2);
+CREATE TABLE t6(
+formattypeid int NOT NULL ,
+name varchar(60) NOT NULL default '',
+priority int default NULL,
+PRIMARY KEY (formattypeid)
+);
+INSERT INTO t6 VALUES
+(2, "Ringtones", 0);
+CREATE TABLE t7(
+metaid int NOT NULL default '0',
+artistid int NOT NULL default '0',
+PRIMARY KEY (metaid,artistid)
+);
+INSERT INTO t7 VALUES
+(4, 5), (3, 4);
+CREATE TABLE t8(
+artistid int NOT NULL ,
+name varchar(80) NOT NULL default '',
+PRIMARY KEY (artistid)
+);
+INSERT INTO t8 VALUES
+(5, "Anastacia"), (4, "John Mayer");
+CREATE TABLE t9(
+subgenreid int NOT NULL default '0',
+metaid int NOT NULL default '0',
+PRIMARY KEY (subgenreid,metaid)
+) ;
+CREATE INDEX t9_subgenreid ON t9(subgenreid);
+CREATE INDEX t9_metaid ON t9(metaid);
+INSERT INTO t9 VALUES
+(138, 4), (31, 3);
+CREATE TABLE t10(
+subgenreid int NOT NULL ,
+genreid int NOT NULL default '0',
+name varchar(80) NOT NULL default '',
+PRIMARY KEY (subgenreid)
+) ;
+CREATE INDEX t10_genreid ON t10(genreid);
+INSERT INTO t10 VALUES
+(138, 19, ''), (31, 3, '');
+CREATE TABLE t11(
+genreid int NOT NULL default '0',
+name char(80) NOT NULL default '',
+priority int NOT NULL default '0',
+masterclip char(1) default NULL,
+PRIMARY KEY (genreid)
+) ;
+CREATE INDEX t11_masterclip ON t11( masterclip);
+INSERT INTO t11 VALUES
+(19, "Pop & Dance", 95, 'Y'), (3, "Rock & Alternative", 100, 'Y');
+set join_cache_level=6;
+EXPLAIN
+SELECT t1.uniquekey, t1.xml AS affiliateXml,
+t8.name AS artistName, t8.artistid,
+t11.name AS genreName, t11.genreid, t11.priority AS genrePriority,
+t10.subgenreid, t10.name AS subgenreName,
+t2.name AS metaName, t2.metaid, t2.xml AS metaXml,
+t4.priority + t5.priority + t6.priority AS overallPriority,
+t3.path AS path, t3.mediaid,
+t4.formatid, t4.name AS formatName,
+t5.formatclassid, t5.name AS formatclassName,
+t6.formattypeid, t6.name AS formattypeName
+FROM t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
+WHERE t7.metaid = t2.metaid AND t7.artistid = t8.artistid AND
+t9.metaid = t2.metaid AND t9.subgenreid = t10.subgenreid AND
+t10.genreid = t11.genreid AND t3.metaid = t2.metaid AND
+t3.formatid = t4.formatid AND t4.formatclassid = t5.formatclassid AND
+t4.canaddtocapability = 'Y' AND t5.formattypeid = t6.formattypeid AND
+t6.formattypeid IN (2) AND (t3.formatid IN (31, 8, 76)) AND
+t1.metaid = t2.metaid AND t1.affiliateid = '2';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t6 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 1
+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)
+1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer (incremental, BKA join)
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (incremental, BKA join)
+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)
+1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (incremental, BKA join)
+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)
+1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer (incremental, BKA join)
+SELECT t1.uniquekey, t1.xml AS affiliateXml,
+t8.name AS artistName, t8.artistid,
+t11.name AS genreName, t11.genreid, t11.priority AS genrePriority,
+t10.subgenreid, t10.name AS subgenreName,
+t2.name AS metaName, t2.metaid, t2.xml AS metaXml,
+t4.priority + t5.priority + t6.priority AS overallPriority,
+t3.path AS path, t3.mediaid,
+t4.formatid, t4.name AS formatName,
+t5.formatclassid, t5.name AS formatclassName,
+t6.formattypeid, t6.name AS formattypeName
+FROM t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
+WHERE t7.metaid = t2.metaid AND t7.artistid = t8.artistid AND
+t9.metaid = t2.metaid AND t9.subgenreid = t10.subgenreid AND
+t10.genreid = t11.genreid AND t3.metaid = t2.metaid AND
+t3.formatid = t4.formatid AND t4.formatclassid = t5.formatclassid AND
+t4.canaddtocapability = 'Y' AND t5.formattypeid = t6.formattypeid AND
+t6.formattypeid IN (2) AND (t3.formatid IN (31, 8, 76)) AND
+t1.metaid = t2.metaid AND t1.affiliateid = '2';
+uniquekey affiliateXml artistName artistid genreName genreid genrePriority subgenreid subgenreName metaName metaid metaXml overallPriority path mediaid formatid formatName formatclassid formatclassName formattypeid formattypeName
+DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
+CREATE TABLE t1 (a1 int, filler1 char(64) default ' ' );
+CREATE TABLE t2 (
+a2 int, b2 int, filler2 char(64) default ' ',
+PRIMARY KEY idx(a2,b2,filler2)
+) ;
+CREATE TABLE t3 (b3 int, c3 int, INDEX idx(b3));
+INSERT INTO t1(a1) VALUES
+(4), (7), (1), (9), (8), (5), (3), (6), (2);
+INSERT INTO t2(a2,b2) VALUES
+(1,30), (3,40), (2,61), (6,73), (8,92), (9,27), (4,18), (5,84), (7,56),
+(4,14), (6,76), (8,98), (7,55), (1,39), (2,68), (3,45), (9,21), (5,81),
+(5,88), (2,65), (6,74), (9,23), (1,37), (3,44), (4,17), (8,99), (7,51),
+(9,28), (7,52), (1,33), (4,13), (5,87), (3,43), (8,91), (2,62), (6,79),
+(3,49), (8,93), (7,34), (5,82), (6,78), (2,63), (1,32), (9,22), (4,11);
+INSERT INTO t3 VALUES
+(30,302), (92,923), (18,187), (45,459), (30,309),
+(39,393), (68,685), (45,458), (21,210), (81,817),
+(40,405), (61,618), (73,738), (92,929), (27,275),
+(18,188), (84,846), (56,564), (14,144), (76,763),
+(98,982), (55,551), (17,174), (99,998), (51,513),
+(28,282), (52,527), (33,336), (13,138), (87,878),
+(43,431), (91,916), (62,624), (79,797), (49,494),
+(93,933), (34,347), (82,829), (78,780), (63,634),
+(32,329), (22,228), (11,114), (74,749), (23,236);
+set join_cache_level=1;
+EXPLAIN
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 Using index
+1 SIMPLE t3 ref idx idx 5 test.t2.b2 5 Using where
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+a1<>a2 a1 a2 b2 b3 c3 s1 s2
+0 4 4 13 13 138
+0 4 4 18 18 188
+0 1 1 30 30 309
+0 1 1 32 32 329
+0 9 9 22 22 228
+0 8 8 92 92 929
+0 8 8 99 99 998
+0 5 5 82 82 829
+0 5 5 87 87 878
+0 3 3 45 45 459
+0 3 3 45 45 458
+0 6 6 73 73 738
+0 6 6 74 74 749
+0 2 2 61 61 618
+set join_cache_level=5;
+set join_buffer_size=512;
+EXPLAIN
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 Using index
+1 SIMPLE t3 ref idx idx 5 test.t2.b2 5 Using where; Using join buffer (flat, BKA join)
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+a1<>a2 a1 a2 b2 b3 c3 s1 s2
+0 4 4 18 18 188
+0 4 4 13 13 138
+0 1 1 30 30 309
+0 1 1 32 32 329
+0 9 9 22 22 228
+0 8 8 92 92 929
+0 8 8 99 99 998
+0 5 5 82 82 829
+0 3 3 45 45 459
+0 3 3 45 45 458
+0 5 5 87 87 878
+0 2 2 61 61 618
+0 6 6 73 73 738
+0 6 6 74 74 749
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int, b int, INDEX idx(b));
+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);
+set join_buffer_size=32;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '32'
+set join_cache_level=8;
+EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 7 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.a 2 Using join buffer (flat, BKAH join)
+SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30;
+a b a b
+7 40 7 10
+7 40 7 10
+7 40 7 20
+8 30 8 10
+8 30 8 20
+DROP TABLE t1,t2;
+#
+# Bug #40134: outer join with not exists optimization and join buffer
+#
+set join_cache_level=default;
+set join_buffer_size=default;
+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);
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref i_a i_a 4 test.t1.a 2 Using where; Not exists
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+a a b
+3 NULL NULL
+5 NULL NULL
+1 NULL NULL
+SET join_cache_level=6;
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref i_a i_a 4 test.t1.a 2 Using where; Not exists; Using join buffer (flat, BKA join)
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+a a b
+3 NULL NULL
+5 NULL NULL
+1 NULL NULL
+DROP TABLE t1, t2;
+set join_cache_level=default;
+set join_buffer_size=default;
+#
+# BUG#40136: Group by is ignored when join buffer is used for an outer join
+#
+create table t1(a int PRIMARY KEY, b int);
+insert into t1 values
+(5, 10), (2, 70), (7, 80), (6, 20), (1, 50), (9, 40), (8, 30), (3, 60);
+create table t2 (p int, a int, INDEX i_a(a));
+insert into t2 values
+(103, 7), (109, 3), (102, 3), (108, 1), (106, 3),
+(107, 7), (105, 1), (101, 3), (100, 7), (110, 1);
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+The following must not show "using join cache":
+explain
+select t1.a, count(t2.p) as count
+from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort
+1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using where; Using join buffer (flat, BKA join)
+select t1.a, count(t2.p) as count
+from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
+a count
+1 1
+2 0
+3 2
+5 0
+6 0
+7 2
+8 0
+9 0
+set join_cache_level=@save_join_cache_level;
+drop table t1, t2;
+#
+# BUG#40268: Nested outer join with not null-rejecting where condition
+# over an inner table which is not the last in the nest
+#
+CREATE TABLE t2 (a int, b int, c int);
+CREATE TABLE t3 (a int, b int, c int);
+CREATE TABLE t4 (a int, b int, c int);
+INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0);
+INSERT INTO t3 VALUES (1,2,0), (2,2,0);
+INSERT INTO t4 VALUES (3,2,0), (4,2,0);
+set join_cache_level=6;
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2 LEFT JOIN (t3, t4) ON t2.b=t4.b
+WHERE t3.a+2<t2.a OR t3.c IS NULL;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+set join_cache_level=default;
+DROP TABLE t2, t3, t4;
+#
+# Bug #40192: outer join with where clause when using BNL
+#
+create table t1 (a int, b int);
+insert into t1 values (2, 20), (3, 30), (1, 10);
+create table t2 (a int, c int);
+insert into t2 values (1, 101), (3, 102), (1, 100);
+set join_cache_level=6;
+select * from t1 left join t2 on t1.a=t2.a;
+a b a c
+1 10 1 101
+3 30 3 102
+1 10 1 100
+2 20 NULL NULL
+explain select * from t1 left join t2 on t1.a=t2.a where t2.c=102 or t2.c is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+select * from t1 left join t2 on t1.a=t2.a where t2.c=102 or t2.c is null;
+a b a c
+3 30 3 102
+2 20 NULL NULL
+set join_cache_level=default;
+drop table t1, t2;
+#
+# Bug #40317: outer join with with constant on expression equal to FALSE
+#
+create table t1 (a int);
+insert into t1 values (30), (40), (20);
+create table t2 (b int);
+insert into t2 values (200), (100);
+set join_cache_level=6;
+select * from t1 left join t2 on (1=0);
+a b
+30 NULL
+40 NULL
+20 NULL
+explain select * from t1 left join t2 on (1=0) where a=40;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+select * from t1 left join t2 on (1=0) where a=40;
+a b
+40 NULL
+set join_cache_level=0;
+explain select * from t1 left join t2 on (1=0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+set join_cache_level=default;
+drop table t1, t2;
+#
+# Bug #41204: small buffer with big rec_per_key for ref access
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1 VALUES (20000), (10000);
+CREATE TABLE t2 (pk int AUTO_INCREMENT PRIMARY KEY, b int, c int, INDEX idx(b));
+INSERT INTO t2(b,c) VALUES (10000, 3), (20000, 7), (20000, 1), (10000, 9), (20000, 5);
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+ANALYZE TABLE t1,t2;
+set join_cache_level=6;
+set join_buffer_size=1024;
+EXPLAIN SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2050 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.a 640 Using join buffer (flat, BKA join)
+SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b;
+AVG(c)
+5.0000
+set join_buffer_size=default;
+set join_cache_level=default;
+DROP TABLE t1, t2;
+#
+# Bug #41894: big join buffer of level 7 used to join records
+# with null values in place of varchar strings
+#
+CREATE TABLE t1 (a int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+b varchar(127) DEFAULT NULL);
+INSERT INTO t1(a) VALUES (1);
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+CREATE TABLE t2 (a int NOT NULL PRIMARY KEY, b varchar(127) DEFAULT NULL);
+INSERT INTO t2 SELECT * FROM t1;
+CREATE TABLE t3 (a int NOT NULL PRIMARY KEY, b varchar(127) DEFAULT NULL);
+INSERT INTO t3 SELECT * FROM t1;
+set join_cache_level=7;
+set join_buffer_size=1024*1024;
+EXPLAIN
+SELECT COUNT(*) FROM t1,t2,t3
+WHERE t1.a=t2.a AND t2.a=t3.a AND
+t1.b IS NULL AND t2.b IS NULL AND t3.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16384 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKAH join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKAH join)
+SELECT COUNT(*) FROM t1,t2,t3
+WHERE t1.a=t2.a AND t2.a=t3.a AND
+t1.b IS NULL AND t2.b IS NULL AND t3.b IS NULL;
+COUNT(*)
+16384
+set join_buffer_size=default;
+set join_cache_level=default;
+DROP TABLE t1,t2,t3;
+#
+# Bug #42020: join buffer is used for outer join with fields of
+# several outer tables in join buffer
+#
+CREATE TABLE t1 (
+a bigint NOT NULL,
+PRIMARY KEY (a)
+);
+INSERT INTO t1 VALUES
+(2), (1);
+CREATE TABLE t2 (
+a bigint NOT NULL,
+b bigint NOT NULL,
+PRIMARY KEY (a,b)
+);
+INSERT INTO t2 VALUES
+(2,30), (2,40), (2,50), (2,60), (2,70), (2,80),
+(1,10), (1, 20), (1,30), (1,40), (1,50);
+CREATE TABLE t3 (
+pk bigint NOT NULL AUTO_INCREMENT,
+a bigint NOT NULL,
+b bigint NOT NULL,
+val bigint DEFAULT '0',
+PRIMARY KEY (pk),
+KEY idx (a,b)
+);
+INSERT INTO t3(a,b) VALUES
+(2,30), (2,40), (2,50), (2,60), (2,70), (2,80),
+(4,30), (4,40), (4,50), (4,60), (4,70), (4,80),
+(5,30), (5,40), (5,50), (5,60), (5,70), (5,80),
+(7,30), (7,40), (7,50), (7,60), (7,70), (7,80);
+set join_cache_level=0;
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+WHERE t1.a=t2.a;
+a a a b b val
+1 1 NULL 10 NULL NULL
+1 1 NULL 20 NULL NULL
+1 1 NULL 30 NULL NULL
+1 1 NULL 40 NULL NULL
+1 1 NULL 50 NULL NULL
+2 2 2 30 30 0
+2 2 2 40 40 0
+2 2 2 50 50 0
+2 2 2 60 60 0
+2 2 2 70 70 0
+2 2 2 80 80 0
+set join_cache_level=6;
+set join_buffer_size=256;
+EXPLAIN
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+WHERE t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using index
+1 SIMPLE t2 ref PRIMARY PRIMARY 8 test.t1.a 1 Using index
+1 SIMPLE t3 ref idx idx 16 test.t1.a,test.t2.b 2 Using join buffer (flat, BKA join)
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+WHERE t1.a=t2.a;
+a a a b b val
+1 1 NULL 10 NULL NULL
+1 1 NULL 20 NULL NULL
+1 1 NULL 30 NULL NULL
+1 1 NULL 40 NULL NULL
+1 1 NULL 50 NULL NULL
+2 2 2 30 30 0
+2 2 2 40 40 0
+2 2 2 50 50 0
+2 2 2 60 60 0
+2 2 2 70 70 0
+2 2 2 80 80 0
+DROP INDEX idx ON t3;
+set join_cache_level=2;
+EXPLAIN
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+WHERE t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using index
+1 SIMPLE t2 ref PRIMARY PRIMARY 8 test.t1.a 1 Using index
+1 SIMPLE t3 ALL NULL NULL NULL NULL 24 Using where; Using join buffer (flat, BNL join)
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+WHERE t1.a=t2.a;
+a a a b b val
+1 1 NULL 10 NULL NULL
+1 1 NULL 20 NULL NULL
+1 1 NULL 30 NULL NULL
+1 1 NULL 40 NULL NULL
+1 1 NULL 50 NULL NULL
+2 2 2 30 30 0
+2 2 2 40 40 0
+2 2 2 50 50 0
+2 2 2 60 60 0
+2 2 2 70 70 0
+2 2 2 80 80 0
+set join_buffer_size=default;
+set join_cache_level=default;
+DROP TABLE t1,t2,t3;
+create table t1(f1 int, f2 int);
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2(f1 int not null, f2 int not null, f3 char(200), key(f1,f2));
+insert into t2 values (1,1, 'qwerty'),(1,2, 'qwerty'),(1,3, 'qwerty');
+insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'),
+(2,4, 'qwerty'),(2,5, 'qwerty');
+insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty');
+insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'),
+(4,4, 'qwerty');
+insert into t2 values (1,1, 'qwerty'),(1,2, 'qwerty'),(1,3, 'qwerty');
+insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'),
+(2,4, 'qwerty'),(2,5, 'qwerty');
+insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty');
+insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'),
+(4,4, 'qwerty');
+set join_cache_level=5;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+f1 f2 f3
+1 1 qwerty
+2 2 qwerty
+1 1 qwerty
+2 2 qwerty
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join)
+set join_cache_level=6;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+f1 f2 f3
+1 1 qwerty
+2 2 qwerty
+1 1 qwerty
+2 2 qwerty
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join)
+set join_cache_level=7;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+f1 f2 f3
+1 1 qwerty
+2 2 qwerty
+1 1 qwerty
+2 2 qwerty
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
+set join_cache_level=8;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+f1 f2 f3
+1 1 qwerty
+2 2 qwerty
+1 1 qwerty
+2 2 qwerty
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
+drop table t1,t2;
+set join_cache_level=default;
+#
+# Bug #42955: join with GROUP BY/ORDER BY and when BKA is enabled
+#
+create table t1 (d int, id1 int, index idx1 (d, id1));
+insert into t1 values
+(3, 20), (2, 40), (3, 10), (1, 10), (3, 20), (1, 40), (2, 30), (3, 30);
+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);
+set join_cache_level=6;
+explain
+select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
+where t1.d=3 group by t1.id1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1 idx1 5 const 4 Using where; Using index; Using temporary; Using filesort
+1 SIMPLE t2 ref idx2 idx2 5 test.t1.id1 2 Using join buffer (flat, BKA join)
+select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
+where t1.d=3 group by t1.id1;
+id1 sum(t2.id2)
+10 900
+20 2000
+30 900
+explain
+select t1.id1 from t1 join t2 on t1.id1=t2.id1
+where t1.d=3 and t2.id2 > 200 order by t1.id1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1 idx1 5 const 4 Using where; Using index; Using temporary; Using filesort
+1 SIMPLE t2 ref idx2 idx2 5 test.t1.id1 2 Using where; Using join buffer (flat, BKA join)
+select t1.id1 from t1 join t2 on t1.id1=t2.id1
+where t1.d=3 and t2.id2 > 200 order by t1.id1;
+id1
+10
+10
+20
+20
+20
+20
+30
+30
+set join_cache_level=default;
+drop table t1,t2;
+#
+# Bug #44019: star-like multi-join query executed join_cache_level=6
+#
+create table t1 (a int, b int, c int, d int);
+create table t2 (b int, e varchar(16), index idx(b));
+create table t3 (d int, f varchar(16), index idx(d));
+create table t4 (c int, g varchar(16), index idx(c));
+insert into t1 values
+(5, 50, 500, 5000), (3, 30, 300, 3000), (9, 90, 900, 9000),
+(2, 20, 200, 2000), (4, 40, 400, 4000), (8, 80, 800, 800),
+(7, 70, 700, 7000);
+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 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 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');
+analyze table t2,t3,t4;
+set join_cache_level=1;
+explain
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+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 5 test.t1.b 1
+1 SIMPLE t3 ref idx idx 5 test.t1.d 1
+1 SIMPLE t4 ref idx idx 5 test.t1.c 1
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+a b c d e f g
+3 30 300 3000 bbb ddd ccc
+set join_cache_level=6;
+explain
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+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 5 test.t1.b 1 Using join buffer (flat, BKA join)
+1 SIMPLE t3 ref idx idx 5 test.t1.d 1 Using join buffer (incremental, BKA join)
+1 SIMPLE t4 ref idx idx 5 test.t1.c 1 Using join buffer (incremental, BKA join)
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+a b c d e f g
+3 30 300 3000 bbb ddd ccc
+set join_cache_level=default;
+drop table t1,t2,t3,t4;
+#
+# Bug #44250: Corruption of linked join buffers when using BKA
+#
+CREATE TABLE t1 (
+id1 bigint(20) DEFAULT NULL,
+id2 bigint(20) DEFAULT NULL,
+id3 bigint(20) DEFAULT NULL,
+num1 bigint(20) DEFAULT NULL,
+num2 int(11) DEFAULT NULL,
+num3 bigint(20) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id3 bigint(20) NOT NULL DEFAULT '0',
+id4 bigint(20) DEFAULT NULL,
+enum1 enum('Enabled','Disabled','Paused') DEFAULT NULL,
+PRIMARY KEY (id3)
+);
+CREATE TABLE t3 (
+id4 bigint(20) NOT NULL DEFAULT '0',
+text1 text,
+PRIMARY KEY (id4)
+);
+CREATE TABLE t4 (
+id2 bigint(20) NOT NULL DEFAULT '0',
+dummy int(11) DEFAULT '0',
+PRIMARY KEY (id2)
+);
+CREATE TABLE t5 (
+id1 bigint(20) NOT NULL DEFAULT '0',
+id2 bigint(20) NOT NULL DEFAULT '0',
+enum2 enum('Active','Deleted','Paused') DEFAULT NULL,
+PRIMARY KEY (id1,id2)
+);
+set join_cache_level=8;
+set join_buffer_size=2048;
+EXPLAIN
+SELECT STRAIGHT_JOIN t1.id1, t1.num3, t3.text1, t3.id4, t2.id3, t4.dummy
+FROM t1 JOIN t2 JOIN t3 JOIN t4 JOIN t5
+WHERE t1.id1=t5.id1 AND t1.id2=t5.id2 and t4.id2=t1.id2 AND
+t5.enum2='Active' AND t3.id4=t2.id4 AND t2.id3=t1.id3 AND t3.text1<'D';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 349 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.id3 1 Using where; Using join buffer (flat, BKAH join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.id4 1 Using where; Using join buffer (incremental, BKAH join)
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.id2 1 Using join buffer (incremental, BKAH join)
+1 SIMPLE t5 eq_ref PRIMARY PRIMARY 16 test.t1.id1,test.t1.id2 1 Using where; Using join buffer (incremental, BKAH join)
+SELECT STRAIGHT_JOIN t1.id1, t1.num3, t3.text1, t3.id4, t2.id3, t4.dummy
+FROM t1 JOIN t2 JOIN t3 JOIN t4 JOIN t5
+WHERE t1.id1=t5.id1 AND t1.id2=t5.id2 and t4.id2=t1.id2 AND
+t5.enum2='Active' AND t3.id4=t2.id4 AND t2.id3=t1.id3 AND t3.text1<'D';
+id1 num3 text1 id4 id3 dummy
+228172702 14 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2567095402 2667134182 0
+228172702 134 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2567095402 2667134182 0
+228172702 15 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2567095402 2667134182 0
+228172702 3 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2567095402 2667134182 0
+228808822 61 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 13 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 60 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 13 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 6 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 18 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 17 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 50 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0
+228808822 89 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 19 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 9 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 84 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 14 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 10 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 26 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 28 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+228808822 62 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0
+set join_buffer_size=default;
+set join_cache_level=default;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# Bug#45267: Incomplete check caused wrong result.
+#
+CREATE TABLE t1 (
+`pk` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
+);
+CREATE TABLE t3 (
+`pk` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
+);
+INSERT INTO t3 VALUES
+(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),
+(16),(17),(18),(19),(20);
+CREATE TABLE t2 (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`time_key` time NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `time_key` (`time_key`)
+);
+INSERT INTO t2 VALUES (10,9,'22:36:46'),(11,0,'08:46:46');
+SELECT DISTINCT t1.`pk`
+FROM t1 RIGHT JOIN t2 STRAIGHT_JOIN t3 ON t2.`int_nokey` ON t2.`time_key`
+GROUP BY 1;
+pk
+NULL
+DROP TABLE IF EXISTS t1, t2, t3;
+#
+# Bug #46328: Use of aggregate function without GROUP BY clause
+# returns many rows (vs. one )
+#
+CREATE TABLE t1 (
+int_key int(11) NOT NULL,
+KEY int_key (int_key)
+);
+INSERT INTO t1 VALUES
+(0),(2),(2),(2),(3),(4),(5),(5),(6),(6),(8),(8),(9),(9);
+CREATE TABLE t2 (
+int_key int(11) NOT NULL,
+KEY int_key (int_key)
+);
+INSERT INTO t2 VALUES (2),(3);
+
+# The query shall return 1 record with a max value 9 and one of the
+# int_key values inserted above (undefined which one). A changed
+# execution plan may change the value in the second column
+SELECT MAX(t1.int_key), t1.int_key
+FROM t1 STRAIGHT_JOIN t2
+ORDER BY t1.int_key;
+MAX(t1.int_key) int_key
+9 0
+
+explain
+SELECT MAX(t1.int_key), t1.int_key
+FROM t1 STRAIGHT_JOIN t2
+ORDER BY t1.int_key;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL int_key 4 NULL 14 Using index
+1 SIMPLE t2 index NULL int_key 4 NULL 2 Using index; Using join buffer (flat, BNL join)
+
+DROP TABLE t1,t2;
+SET join_cache_level=default;
+#
+# Regression test for
+# Bug#46733 - NULL value not returned for aggregate on empty result
+# set w/ semijoin on
+#
+CREATE TABLE t1 (
+i int(11) NOT NULL,
+v varchar(1) DEFAULT NULL,
+PRIMARY KEY (i)
+);
+INSERT INTO t1 VALUES (10,'a'),(11,'b'),(12,'c'),(13,'d');
+CREATE TABLE t2 (
+i int(11) NOT NULL,
+v varchar(1) DEFAULT NULL,
+PRIMARY KEY (i)
+);
+INSERT INTO t2 VALUES (1,'x'),(2,'y');
+
+SELECT MAX(t1.i)
+FROM t1 JOIN t2 ON t2.v
+ORDER BY t2.v;
+MAX(t1.i)
+NULL
+
+EXPLAIN
+SELECT MAX(t1.i)
+FROM t1 JOIN t2 ON t2.v
+ORDER BY t2.v;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index; Using join buffer (flat, BNL join)
+
+DROP TABLE t1,t2;
+#
+# Bug #45092: join buffer contains two blob columns one of which is
+# used in the key employed to access the joined table
+#
+CREATE TABLE t1 (c1 int, c2 int, key (c2));
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t1 VALUES (2,2);
+CREATE TABLE t2 (c1 text, c2 text);
+INSERT INTO t2 VALUES('tt', 'uu');
+INSERT INTO t2 VALUES('zzzz', 'xxxxxxxxx');
+ANALYZE TABLE t1,t2;
+set join_cache_level=6;
+SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH(t2.c2) FROM t1,t2
+WHERE t1.c2=LENGTH(t2.c2) and t1.c1=LENGTH(t2.c1);
+c1 c2 c1 c2 LENGTH(t2.c1) LENGTH(t2.c2)
+2 2 tt uu 2 2
+set join_cache_level=default;
+DROP TABLE t1,t2;
+#
+# Bug #51092: linked join buffer is used for a 3-way cross join query
+# that selects only records of the first table
+#
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,2);
+create table t3 (a int, b int);
+insert into t3 values (1,1),(2,2);
+explain select t1.* from t1,t2,t3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+select t1.* from t1,t2,t3;
+a b
+1 1
+2 2
+1 1
+2 2
+1 1
+2 2
+1 1
+2 2
+set join_cache_level=2;
+explain select t1.* from t1,t2,t3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+select t1.* from t1,t2,t3;
+a b
+1 1
+2 2
+1 1
+2 2
+1 1
+2 2
+1 1
+2 2
+set join_cache_level=default;
+drop table t1,t2,t3;
+#
+# Bug #52394: using join buffer for 3 table join with ref access
+# LP #623209: and no references to the columns of the middle table
+#
+set join_cache_level=6;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (6,'r'),(27,'o');
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES(1),(2),(3),(4),(5);
+CREATE TABLE t3 (a int(11) primary key, b varchar(1));
+INSERT INTO t3 VALUES
+(14,'d'),(15,'z'),(16,'e'),(17,'h'),(18,'b'),(19,'s'),(20,'e'),
+(21,'j'),(22,'e'),(23,'f'),(24,'v'),(25,'x'),(26,'m'),(27,'o');
+EXPLAIN
+SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
+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 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (incremental, BKA join)
+SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
+a
+27
+27
+27
+27
+27
+DROP TABLE t1,t2,t3;
+set join_cache_level=default;
+#
+# Bug #51084: Batched key access crashes for SELECT with
+# derived table and LEFT JOIN
+#
+CREATE TABLE t1 (
+carrier int,
+id int PRIMARY KEY
+);
+INSERT INTO t1 VALUES (1,11),(1,12),(2,13);
+CREATE TABLE t2 (
+scan_date int,
+package_id int
+);
+INSERT INTO t2 VALUES (2008,21),(2008,22);
+CREATE TABLE t3 (
+carrier int PRIMARY KEY,
+id int
+);
+INSERT INTO t3 VALUES (1,31);
+CREATE TABLE t4 (
+carrier_id int,
+INDEX carrier_id(carrier_id)
+);
+INSERT INTO t4 VALUES (31),(32);
+SET join_cache_level=8;
+SELECT COUNT(*)
+FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+ON t3.carrier = t1.carrier;
+COUNT(*)
+6
+EXPLAIN
+SELECT COUNT(*)
+FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+ON t3.carrier = t1.carrier;
+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 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.carrier 1 Using where
+1 SIMPLE t4 ref carrier_id carrier_id 5 test.t3.id 2 Using index
+SET join_cache_level=default;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #52636: allowing JOINs on NULL values w/ join_cache_level = 5-8
+#
+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);
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+a
+NULL
+NULL
+set join_cache_level = 8;
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKAH join)
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+a
+NULL
+NULL
+delete from t1;
+INSERT INTO t1 VALUES (NULL),(NULL);
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+a
+NULL
+NULL
+DROP TABLE t1,t2;
+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");
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+a
+NULL
+NULL
+set join_cache_level = 8;
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer (flat, BKAH join)
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+a
+NULL
+NULL
+set join_cache_level = default;
+DROP TABLE t1,t2;
+#
+# Bug #54359: Extra rows with join_cache_level=7,8 and two joins
+# and multi-column index"
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+a int DEFAULT NULL,
+b varchar(16) DEFAULT NULL,
+c varchar(16) DEFAULT NULL,
+INDEX idx (b,a))
+;
+INSERT INTO t1 VALUES (4,9,'k','k');
+INSERT INTO t1 VALUES (12,5,'k','k');
+set join_cache_level = 8;
+EXPLAIN
+SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx)
+WHERE s.pk AND s.a >= t.pk AND s.b = t.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE s ref idx idx 19 test.t.c 1 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
+SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx)
+WHERE s.pk AND s.a >= t.pk AND s.b = t.c;
+a
+9
+9
+set join_cache_level = default;
+DROP TABLE t1;
+#
+# Bug #54235: Extra rows with join_cache_level=6,8 and two LEFT JOINs
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t1 VALUES (null), (2), (null), (1);
+set join_cache_level = 6;
+EXPLAIN
+SELECT t1.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
+WHERE t1.a OR t3.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
+SELECT t1.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
+WHERE t1.a OR t3.a;
+a
+2
+1
+EXPLAIN
+SELECT t1.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
+WHERE t1.a OR t4.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
+SELECT t1.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
+WHERE t1.a OR t4.a;
+a
+2
+1
+set join_cache_level = default;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #663840: Memory overwrite causing crash with hash join
+#
+SET SESSION join_cache_level=3;
+SET SESSION join_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '100'
+CREATE TABLE t3 (
+i int NOT NULL,
+j int NOT NULL,
+d date NOT NULL,
+t time NOT NULL,
+v varchar(1) NOT NULL,
+u varchar(1) NOT NULL,
+INDEX idx (v)
+) COLLATE=latin1_bin;
+INSERT INTO t3 VALUES
+(3,8,'2008-12-04','00:00:00','v','v'), (3,8,'2009-03-28','00:00:00','f','f'),
+(3,5,'1900-01-01','00:55:47','v','v'), (2,8,'2009-10-02','00:00:00','s','s'),
+(1,8,'1900-01-01','20:51:59','a','a'), (0,6,'2008-06-04','09:47:27','p','p'),
+(8,7,'2009-01-13','21:58:29','z','z'), (5,2,'1900-01-01','22:45:53','a','a'),
+(9,5,'2008-01-28','14:06:48','h','h'), (5,7,'2004-09-18','22:17:16','h','h'),
+(4,2,'2006-10-14','14:59:37','v','v'), (2,9,'1900-01-01','23:37:40','v','v'),
+(33,142,'2000-11-28','14:14:01','b','b'), (5,3,'2008-04-04','02:54:19','y','y'),
+(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');
+CREATE TABLE t1 SELECT * FROM t3;
+DELETE FROM t1 WHERE i > 8;
+CREATE TABLE t2 SELECT * FROM t3;
+DELETE FROM t2 WHERE j > 10;
+EXPLAIN
+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;
+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 ref idx idx 3 test.t2.u 2 Using where
+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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
+DROP TABLE t1,t2,t3;
+SET SESSION join_cache_level=DEFAULT;
+SET SESSION join_buffer_size=DEFAULT;
+#
+# Bug #664508: 'Simple' GROUP BY + ORDER BY
+# when join buffers are used
+#
+CREATE TABLE t1 (
+pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2 (v,i)
+) COLLATE latin1_bin;
+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');
+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)
+) COLLATE latin1_bin;
+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');
+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)
+) COLLATE latin1_bin;
+INSERT INTO t3 VALUES
+(1,9,'x'), (2,5,'g'), (3,1,'o'), (4,0,'g'), (5,1,'v'),
+(6,190,'m'), (7,6,'x'), (8,3,'c'), (9,4,'z'), (10,3,'i'),
+(11,186,'x'), (12,1,'g'), (13,8,'q'), (14,226,'m'), (15,133,'p'),
+(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
+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
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+v
+h
+z
+p
+n
+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
+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)
+1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 2 Using join buffer (incremental, BKA join)
+SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+v
+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
+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, BNLH join)
+1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 2 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
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+v
+h
+z
+n
+v
+p
+DROP TABLE t1,t2,t3;
+SET SESSION join_cache_level=DEFAULT;
+#
+# Bug #668290: hash join with non-binary collations
+#
+CREATE TABLE t1 (
+i int DEFAULT NULL,
+cl varchar(10) CHARACTER SET latin1 DEFAULT NULL,
+cu varchar(10) CHARACTER SET utf8 DEFAULT NULL,
+INDEX cl (cl),
+INDEX cu (cu)
+);
+INSERT INTO t1 VALUES
+(650903552,'cmxffkpsel','z'), (535298048,'tvtjrcmxff','y'),
+(1626865664,'when','for'), (39649280,'rcvljitvtj','ercvljitvt'),
+(792068096,'ttercvljit','jttercvlji');
+INSERT INTO t1 SELECT * FROM t1;
+CREATE TABLE t2 (
+cu varchar(10) CHARACTER SET utf8 DEFAULT NULL,
+i int DEFAULT NULL,
+cl varchar(10) CHARACTER SET latin1 DEFAULT NULL,
+INDEX cu (cu),
+INDEX cl (cl)
+);
+INSERT INTO t2 VALUES
+('g',7,'like'), ('fujttercvl',6,'y'),
+('s',2,'e'), ('didn\'t',0,'v'),
+ ('gvdrodpedk',8,'chogvdrodp'), ('jichogvdro',7,'will');
+EXPLAIN
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6
+1 SIMPLE t1 ref cu cu 33 func 2 Using where; Using index
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+i
+6
+6
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6
+1 SIMPLE t1 ref cu cu 33 func 2 Using where; Using index; Using join buffer (flat, BNLH join)
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+i
+6
+6
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #669382: hash join using a ref with constant key parts
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES
+(9), (11), (7), (8), (4), (1), (12), (3), (5);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+CREATE TABLE t2 (a int, b int, c int, INDEX idx (a,b));
+INSERT INTO t2 VALUES
+(8, 80, 800), (1, 10, 100), (1, 11, 101), (3, 30, 300),
+(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);
+SET SESSION join_cache_level = 4;
+SET SESSION join_buffer_size = 192;
+EXPLAIN
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 36 Using where
+1 SIMPLE t2 ref idx idx 10 test.t1.a,const 2 Using join buffer (flat, BNLH join)
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
+a c
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #671901: hash join using a ref to a varchar field
+#
+CREATE TABLE t1 (
+v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+i int DEFAULT NULL
+);
+INSERT INTO t1 VALUES
+('k',8), ('abcdefjh',-575340544), ('f',77), ('because', 2), ('f',-517472256),
+('abcdefjhj',5), ('z',7);
+CREATE TABLE t2 (
+v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+i int DEFAULT NULL,
+INDEX idx (v)
+);
+INSERT INTO t2 VALUES
+('did',5), ('was',-1631322112), ('are',3), ('abcdefjhjk',3),
+('abcdefjhjk',4), ('tell',-824573952), ('t',0),('v',-1711013888),
+('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464),
+('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296),
+('ff', 5), ('abcdefjhjk',-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
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+v i
+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
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+v i
+f 5
+f 5
+SET SESSION join_cache_level = 4;
+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 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
+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 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
+f 5
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+# Bug #672497: 3 way join with tiny incremental join buffer with
+# and a ref access from the first table
+#
+CREATE TABLE t1 (
+pk int PRIMARY KEY,
+v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+INDEX idx (v)
+);
+INSERT INTO t1 VALUES
+(1,'abcdefjhjk'), (2,'i'),(3,'abcdefjhjk'), (4,'well'), (5,'abcdefjhjk'),
+(6,'abcdefjhjk'), (7,'that');
+CREATE TABLE t2 (
+pk int PRIMARY KEY,
+i int DEFAULT NULL,
+v varchar(1000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+INDEX idx (v)
+);
+INSERT INTO t2 VALUES
+(1,6,'yes'), (2,NULL,'will'), (3,NULL,'o'), (4,NULL,'k'), (5,NULL,'she'),
+(6,-1450835968,'abcdefjhjkl'), (7,-975831040,'abcdefjhjkl'), (8,NULL,'z'),
+(10,-343932928,'t'),
+(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');
+CREATE TABLE t3 (
+pk int NOT NULL PRIMARY KEY,
+i int,
+v varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+INDEX idx (v(333))
+);
+INSERT INTO t3 VALUES
+(1,7,'abcdefjhjkl'),(2,6,'y'), (3,NULL,'to'),(4,7,'n'),(5,7,'look'), (6,NULL,'all'),
+(7,1443168256,'c'), (8,1427046400,'right'),
+(11,7,'abcdefjhjkl'), (12,6,'y'), (13,NULL,'to'), (14,7,'n'), (15,7,'look'),
+(16,NULL,'all'), (17,1443168256,'c'), (18,1427046400,'right'),
+(21,7,'abcdefjhjkl'), (22,6,'y'), (23,NULL,'to'), (24,7,'n'), (25,7,'look'),
+(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');
+SET SESSION join_buffer_size = 192;
+SET SESSION join_cache_level = 4;
+EXPLAIN
+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 ref idx idx 1003 test.t1.v 2 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t3 ref idx idx 1002 func 3 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
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+DROP TABLE t1,t2,t3;
+#
+# Bug #672551: hash join over a long varchar field
+#
+CREATE TABLE t1 (
+pk int PRIMARY KEY,
+a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
+INDEX idx (a)
+);
+INSERT INTO t1 VALUES (2, 'aa'), (5, 'ccccccc'), (3, 'bb');
+CREATE TABLE t2(
+pk int PRIMARY KEY,
+a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
+INDEX idx (a)
+);
+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');
+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
+3 bb 4 bb
+3 bb 32 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 ref idx idx 515 test.t1.a 2 Using join buffer (flat, BNLH join)
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+pk a pk a
+2 aa 30 aa
+3 bb 4 bb
+2 aa 31 aa
+3 bb 32 bb
+2 aa 42 aa
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #674431: nested outer join when join_cache_level is set to 7
+#
+CREATE TABLE t1 (a int, b varchar(32)) ;
+INSERT INTO t1 VALUES (5,'h'), (NULL,'j');
+CREATE TABLE t2 (a int, b varchar(32), c int) ;
+INSERT INTO t2 VALUES (5,'h',100), (NULL,'j',200);
+CREATE TABLE t3 (a int, b varchar(32), INDEX idx(b));
+INSERT INTO t3 VALUES (77,'h'), (88,'g');
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 7;
+SELECT t3.a
+FROM t1 LEFT JOIN
+(t2 LEFT OUTER JOIN t3 ON t2.b = t3.b) ON t2.a = t1.b
+WHERE t3.a BETWEEN 3 AND 11 OR t1.a <= t2.c;
+a
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2,t3;
+#
+# Bug #52540: nested outer join when join_cache_level is set to 3
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2);
+CREATE TABLE t2 (a varchar(10));
+INSERT INTO t2 VALUES ('f'),('x');
+CREATE TABLE t3 (pk int(11) PRIMARY KEY);
+INSERT INTO t3 VALUES (2);
+CREATE TABLE t4 (a varchar(10));
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 3;
+SELECT *
+FROM t2 LEFT JOIN
+((t1 JOIN t3 ON t1.a = t3.pk) LEFT JOIN t4 ON 1) ON 1;
+a a pk a
+f 2 2 NULL
+x 2 2 NULL
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #674423: outer join with ON expression over only outer tables
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES ('9');
+CREATE TABLE t2 (pk int, a int) ;
+INSERT INTO t2 VALUES ('9',NULL), ('1',NULL);
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9;
+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 ALL NULL NULL NULL NULL 1 Using where
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <>0 OR t2.pk < 9;
+pk a a
+1 NULL NULL
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9;
+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 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9;
+pk a a
+1 NULL NULL
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #675095: nested outer join using join buffer
+#
+CREATE TABLE t1 (pk int, a1 int) ;
+INSERT IGNORE INTO t1 VALUES (2,NULL), (8,0);
+CREATE TABLE t2 (pk int, a2 int, c2 int, d2 int) ;
+INSERT IGNORE INTO t2 VALUES (9,0,0,2), (1,0,0,7);
+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);
+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';
+SET SESSION join_cache_level = 0;
+EXPLAIN EXTENDED
+SELECT *
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+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
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t4 ref idx idx 5 test.t1.a1 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a1` AS `a1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`c2` AS `c2`,`test`.`t2`.`d2` AS `d2`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`a3` AS `a3`,`test`.`t3`.`c3` AS `c3`,`test`.`t3`.`d3` AS `d3`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`a4` AS `a4`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`a5` AS `a5` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`d2` = `test`.`t1`.`pk`) and (`test`.`t3`.`a3` = `test`.`t2`.`c2`))) left join `test`.`t4` on(((`test`.`t4`.`a4` = `test`.`t1`.`a1`) and (`test`.`t1`.`a1` is not null))) left join `test`.`t5` on((`test`.`t5`.`a5` = `test`.`t3`.`a3`)) where 1
+SELECT *
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+pk a1 pk a2 c2 d2 pk a3 c3 d3 pk a4 pk a5
+2 NULL 9 0 0 2 9 0 0 2 NULL NULL 2 0
+2 NULL 9 0 0 2 9 0 0 2 NULL NULL 8 0
+2 NULL 9 0 0 2 1 0 0 7 NULL NULL 2 0
+2 NULL 9 0 0 2 1 0 0 7 NULL NULL 8 0
+8 0 NULL NULL NULL NULL NULL NULL NULL NULL 8 0 NULL NULL
+SET SESSION join_cache_level = 2;
+EXPLAIN EXTENDED
+SELECT *
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+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; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ref idx idx 5 test.t1.a1 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a1` AS `a1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`c2` AS `c2`,`test`.`t2`.`d2` AS `d2`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`a3` AS `a3`,`test`.`t3`.`c3` AS `c3`,`test`.`t3`.`d3` AS `d3`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`a4` AS `a4`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`a5` AS `a5` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`d2` = `test`.`t1`.`pk`) and (`test`.`t3`.`a3` = `test`.`t2`.`c2`))) left join `test`.`t4` on(((`test`.`t4`.`a4` = `test`.`t1`.`a1`) and (`test`.`t1`.`a1` is not null))) left join `test`.`t5` on((`test`.`t5`.`a5` = `test`.`t3`.`a3`)) where 1
+SELECT *
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+pk a1 pk a2 c2 d2 pk a3 c3 d3 pk a4 pk a5
+2 NULL 9 0 0 2 9 0 0 2 NULL NULL 2 0
+2 NULL 9 0 0 2 1 0 0 7 NULL NULL 2 0
+2 NULL 9 0 0 2 9 0 0 2 NULL NULL 8 0
+2 NULL 9 0 0 2 1 0 0 7 NULL NULL 8 0
+8 0 NULL NULL NULL NULL NULL NULL NULL NULL 8 0 NULL NULL
+SET SESSION join_cache_level = 1;
+EXPLAIN EXTENDED
+SELECT *
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+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
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t4 ref idx idx 5 test.t1.a1 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a1` AS `a1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`c2` AS `c2`,`test`.`t2`.`d2` AS `d2`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`a3` AS `a3`,`test`.`t3`.`c3` AS `c3`,`test`.`t3`.`d3` AS `d3`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`a4` AS `a4`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`a5` AS `a5` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`d2` = `test`.`t1`.`pk`) and (`test`.`t3`.`a3` = `test`.`t2`.`c2`))) left join `test`.`t4` on(((`test`.`t4`.`a4` = `test`.`t1`.`a1`) and (`test`.`t1`.`a1` is not null))) left join `test`.`t5` on((`test`.`t5`.`a5` = `test`.`t3`.`a3`)) where 1
+SELECT *
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+pk a1 pk a2 c2 d2 pk a3 c3 d3 pk a4 pk a5
+2 NULL 9 0 0 2 9 0 0 2 NULL NULL 2 0
+2 NULL 9 0 0 2 1 0 0 7 NULL NULL 2 0
+2 NULL 9 0 0 2 9 0 0 2 NULL NULL 8 0
+2 NULL 9 0 0 2 1 0 0 7 NULL NULL 8 0
+8 0 NULL NULL NULL NULL NULL NULL NULL NULL 8 0 NULL NULL
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# Bug #675516: nested outer join with 3 tables in the nest
+# using BNL + BNLH
+#
+CREATE TABLE t1 (a1 int, b1 int, c1 int) ;
+INSERT INTO t1 VALUES (7,8,0), (6,4,0);
+CREATE TABLE t2 (a2 int) ;
+INSERT INTO t2 VALUES (5);
+CREATE TABLE t3 (a3 int, b3 int, c3 int, PRIMARY KEY (b3)) ;
+INSERT INTO t3 VALUES (2,5,0);
+CREATE TABLE t4 (a4 int, b4 int, c4 int) ;
+INSERT INTO t4 VALUES (7,8,0);
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM
+t1 LEFT JOIN
+((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+WHERE t3.a3 IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+SELECT * FROM
+t1 LEFT JOIN
+((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+WHERE t3.a3 IS NULL;
+a1 b1 c1 a2 a3 b3 c3 a4 b4 c4
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT * FROM
+t1 LEFT JOIN
+((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+WHERE t3.a3 IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where
+SELECT * FROM
+t1 LEFT JOIN
+((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+WHERE t3.a3 IS NULL;
+a1 b1 c1 a2 a3 b3 c3 a4 b4 c4
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #660963: nested outer join with join_cache_level set to 5
+#
+CREATE TABLE t1 (a1 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 (a2 int, b2 int, PRIMARY KEY (a2)) ;
+INSERT INTO t2 VALUES (2,1);
+CREATE TABLE t3 (a3 int, b3 int, PRIMARY KEY (a3)) ;
+INSERT INTO t3 VALUES (2,1);
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 6;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where; Using join buffer (incremental, BKA join)
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+a1 a2 b2 a3 b3
+0 2 1 2 1
+0 2 1 2 1
+SET SESSION join_cache_level = 5;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where; Using join buffer (incremental, BNLH join)
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+a1 a2 b2 a3 b3
+0 2 1 2 1
+0 2 1 2 1
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2,t3;
+#
+# Bug #675922: incremental buffer for BKA with access from previous
+# buffers from non-nullable columns whose values may be null
+#
+CREATE TABLE t1 (a1 varchar(32)) ;
+INSERT INTO t1 VALUES ('s'),('k');
+CREATE TABLE t2 (a2 int PRIMARY KEY, b2 varchar(32)) ;
+INSERT INTO t2 VALUES (7,'s');
+CREATE TABLE t3 (a3 int PRIMARY KEY, b3 varchar(32)) ;
+INSERT INTO t3 VALUES (7,'s');
+CREATE TABLE t4 (a4 int) ;
+INSERT INTO t4 VALUES (9);
+CREATE TABLE t5(a5 int PRIMARY KEY, b5 int) ;
+INSERT INTO t5 VALUES (7,0);
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT t4.a4, t5.b5
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where
+SELECT t4.a4, t5.b5
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+a4 b5
+9 0
+9 NULL
+SET SESSION join_cache_level = 6;
+EXPLAIN
+SELECT t4.a4, t5.b5
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where; Using join buffer (incremental, BKA join)
+SELECT t4.a4, t5.b5
+FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+a4 b5
+9 0
+9 NULL
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# Bug #670380: hash join for non-binary collation
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a varchar(32));
+CREATE TABLE t2 (pk int PRIMARY KEY, a varchar(32), INDEX idx(a));
+INSERT INTO t1 VALUES
+(10,'AAA'), (20,'BBBB'), (30,'Cc'), (40,'DD'), (50,'ee');
+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');
+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 ref idx idx 35 test.t1.a 2 Using join buffer (flat, BNLH join)
+SELECT * FROM t1,t2 WHERE t1.a=t2.a;
+pk a pk a
+20 BBBB 1 Bbbb
+20 BBBB 3 bbbb
+10 AAA 4 AaA
+30 Cc 5 CC
+30 Cc 6 cC
+10 AAA 8 AAA
+20 BBBB 9 bBbB
+40 DD 12 dd
+50 ee 13 EE
+50 ee 14 ee
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #694092: incorrect detection of index only pushdown conditions
+#
+CREATE TABLE t1 (
+f1 varchar(10), f3 int(11), PRIMARY KEY (f3)
+);
+INSERT INTO t1 VALUES ('y',1),('or',5);
+CREATE TABLE t2 (
+f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3)
+);
+INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m');
+SET SESSION join_cache_level = 1;
+SET SESSION optimizer_switch = 'index_condition_pushdown=off';
+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 where; Using MRR
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using MRR; Using join buffer (flat, BNL join)
+SELECT * FROM t1,t2
+WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
+f1 f3 f3 f2 f4
+SET SESSION optimizer_switch = 'index_condition_pushdown=on';
+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; Using MRR
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using MRR; Using join buffer (flat, BNL join)
+SELECT * FROM t1,t2
+WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
+f1 f3 f3 f2 f4
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION optimizer_switch = DEFAULT;
+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 7965e287da2..373472f73ce 100644
--- a/mysql-test/r/join_nested.result
+++ b/mysql-test/r/join_nested.result
@@ -74,7 +74,7 @@ WHERE t3.a=1 OR t3.c IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
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`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
@@ -150,7 +150,7 @@ WHERE t3.a>1 OR t3.c IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t5 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`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
@@ -180,7 +180,7 @@ WHERE (t3.a>1 OR t3.c IS NULL) AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+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
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`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
@@ -229,8 +229,8 @@ t8
ON t7.b=t8.b AND t6.b < 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
-1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
+1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
@@ -544,14 +544,14 @@ t0.b=t1.b AND
(t2.a >= 4 OR t2.c IS NULL);
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
+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
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+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
-1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00
-1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00
+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
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -639,7 +639,7 @@ t0.b=t1.b AND
(t9.a=1);
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
+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
@@ -647,7 +647,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+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`)))
SELECT t9.a,t9.b
@@ -836,9 +836,9 @@ ON t3.a=1 AND t2.b=t4.b
WHERE t1.a <= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
+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
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)
CREATE INDEX idx_b ON t2(b);
@@ -850,11 +850,11 @@ LEFT JOIN
ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
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
-1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 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`)))) where 1
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on((((`test`.`t3`.`a` = 1) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`))) and (`test`.`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
@@ -906,7 +906,7 @@ t0.b=t1.b AND
(t9.a=1);
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
+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
@@ -914,7 +914,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+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`)))
CREATE INDEX idx_b ON t4(b);
@@ -956,7 +956,7 @@ t0.b=t1.b AND
(t9.a=1);
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
+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 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
@@ -964,9 +964,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) 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`)))
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,
@@ -1005,7 +1005,7 @@ t0.b=t1.b AND
(t9.a=1);
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
+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 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
@@ -1013,9 +1013,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) 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`)))
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
EXPLAIN EXTENDED
@@ -1055,7 +1055,7 @@ t0.b=t1.b AND
(t9.a=1);
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 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 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
@@ -1063,9 +1063,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) 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`)))
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
@@ -1196,13 +1196,13 @@ INSERT INTO t3 VALUES (0), (1), (2), (3), (4), (5);
EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
-1 SIMPLE t3 index c c 5 NULL 6 Using index
+1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
-1 SIMPLE t3 index c c 5 NULL 6 Using index
-1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
+1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL 0 0
@@ -1272,8 +1272,8 @@ DELETE FROM t3;
EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
-1 SIMPLE t3 index c c 5 NULL 0 Using index
-1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
+1 SIMPLE t3 index c c 5 NULL 0 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL NULL NULL
@@ -1317,8 +1317,8 @@ c11 c21 c31
EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 0
-1 SIMPLE t3 ALL NULL NULL NULL NULL 0
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL);
INSERT INTO t1 VALUES (23, 2340), (26, 9900);
@@ -1445,26 +1445,26 @@ explain select * from t4 join
t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
-1 SIMPLE t3 ref a a 5 test.t2.b X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t5 ref a a 5 test.t3.b X
-1 SIMPLE t4 ref a a 5 test.t3.b X Using where
+1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
-1 SIMPLE t3 ref a a 5 test.t2.b X Using where
-1 SIMPLE t4 ref a a 5 test.t3.b X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using index condition
+1 SIMPLE t4 ref a a 5 test.t3.b X Using where
1 SIMPLE t6 ref a a 5 test.t4.b X
-1 SIMPLE t5 ref a a 5 test.t2.b X
+1 SIMPLE t5 ref a a 5 test.t2.b X Using where
1 SIMPLE t7 ref a a 5 test.t5.b X
explain select * from t2 left join
(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
join t5 on t5.a=t3.b) on t3.a=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
-1 SIMPLE t3 ref a a 5 test.t2.b X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t5 ref a a 5 test.t3.b X
-1 SIMPLE t4 ref a a 5 test.t5.a X
+1 SIMPLE t4 ref a a 5 test.t5.a X Using where
1 SIMPLE t6 ref a a 5 test.t4.b X
drop table t0, t1, t2, t3, t4, t5, t6, t7;
create table t1 (a int);
@@ -1478,8 +1478,8 @@ explain select * from t1 left join
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 10
-1 SIMPLE t2 ref a a 5 test.t1.a 1
-1 SIMPLE t3 ref a a 5 test.t1.a 1
+1 SIMPLE t2 ref a a 5 test.t1.a 1 Using where
+1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where
drop table t1, t2, t3;
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10));
CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10));
@@ -1729,9 +1729,9 @@ LEFT JOIN
(t5 JOIN t4 ON t5.carrier_id = t4.id)
ON t4.carrier = t1.carrier;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index package_id package_id 5 NULL 45 Using index
+1 SIMPLE t2 index package_id package_id 5 NULL 45 Using where; Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1
-1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1
+1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1 Using where
1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index
1 SIMPLE t3 ref package_id package_id 5 test.t1.id 1 Using where; Using index
SELECT COUNT(*)
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
new file mode 100644
index 00000000000..ea637486c40
--- /dev/null
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -0,0 +1,1918 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+CREATE TABLE t0 (a int, b int, c int);
+CREATE TABLE t1 (a int, b int, c int);
+CREATE TABLE t2 (a int, b int, c int);
+CREATE TABLE t3 (a int, b int, c int);
+CREATE TABLE t4 (a int, b int, c int);
+CREATE TABLE t5 (a int, b int, c int);
+CREATE TABLE t6 (a int, b int, c int);
+CREATE TABLE t7 (a int, b int, c int);
+CREATE TABLE t8 (a int, b int, c int);
+CREATE TABLE t9 (a int, b int, c int);
+INSERT INTO t0 VALUES (1,1,0), (1,2,0), (2,2,0);
+INSERT INTO t1 VALUES (1,3,0), (2,2,0), (3,2,0);
+INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0);
+INSERT INTO t3 VALUES (1,2,0), (2,2,0);
+INSERT INTO t4 VALUES (3,2,0), (4,2,0);
+INSERT INTO t5 VALUES (3,1,0), (2,2,0), (3,3,0);
+INSERT INTO t6 VALUES (3,2,0), (6,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 t9 VALUES (1,1,0), (1,2,0), (3,3,0);
+SELECT t2.a,t2.b
+FROM t2;
+a b
+3 3
+4 2
+5 3
+SELECT t3.a,t3.b
+FROM t3;
+a b
+1 2
+2 2
+SELECT t4.a,t4.b
+FROM t4;
+a b
+3 2
+4 2
+SELECT t3.a,t3.b,t4.a,t4.b
+FROM t3,t4;
+a b a b
+1 2 3 2
+2 2 3 2
+1 2 4 2
+2 2 4 2
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t2.b=t4.b;
+a b a b a b
+4 2 1 2 3 2
+4 2 2 2 3 2
+4 2 1 2 4 2
+4 2 2 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t2.b=t4.b
+WHERE t3.a=1 OR t3.c IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
+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 2 100.00 Using where; 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`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t2.b=t4.b
+WHERE t3.a=1 OR t3.c IS NULL;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t2.b=t4.b
+WHERE t3.a>1 OR t3.c IS NULL;
+a b a b a b
+4 2 2 2 3 2
+4 2 2 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+SELECT t5.a,t5.b
+FROM t5;
+a b
+3 1
+2 2
+3 3
+SELECT t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+FROM t3,t4,t5;
+a b a b a b
+1 2 3 2 3 1
+2 2 3 2 3 1
+1 2 4 2 3 1
+2 2 4 2 3 1
+1 2 3 2 2 2
+2 2 3 2 2 2
+1 2 4 2 2 2
+2 2 4 2 2 2
+1 2 3 2 3 3
+2 2 3 2 3 3
+1 2 4 2 3 3
+2 2 4 2 3 3
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+FROM t2
+LEFT JOIN
+(t3, t4, t5)
+ON t2.b=t4.b;
+a b a b a b a b
+4 2 1 2 3 2 3 1
+4 2 2 2 3 2 3 1
+4 2 1 2 4 2 3 1
+4 2 2 2 4 2 3 1
+4 2 1 2 3 2 2 2
+4 2 2 2 3 2 2 2
+4 2 1 2 4 2 2 2
+4 2 2 2 4 2 2 2
+4 2 1 2 3 2 3 3
+4 2 2 2 3 2 3 3
+4 2 1 2 4 2 3 3
+4 2 2 2 4 2 3 3
+3 3 NULL NULL NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+FROM t2
+LEFT JOIN
+(t3, t4, t5)
+ON t2.b=t4.b
+WHERE t3.a>1 OR t3.c IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
+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 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t5 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`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+FROM t2
+LEFT JOIN
+(t3, t4, t5)
+ON t2.b=t4.b
+WHERE t3.a>1 OR t3.c IS NULL;
+a b a b a b a b
+4 2 2 2 3 2 3 1
+4 2 2 2 4 2 3 1
+4 2 2 2 3 2 2 2
+4 2 2 2 4 2 2 2
+4 2 2 2 3 2 3 3
+4 2 2 2 4 2 3 3
+3 3 NULL NULL NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+FROM t2
+LEFT JOIN
+(t3, t4, t5)
+ON t2.b=t4.b
+WHERE (t3.a>1 OR t3.c IS NULL) AND
+(t5.a<3 OR t5.c IS NULL);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
+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 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; 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`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+FROM t2
+LEFT JOIN
+(t3, t4, t5)
+ON t2.b=t4.b
+WHERE (t3.a>1 OR t3.c IS NULL) AND
+(t5.a<3 OR t5.c IS NULL);
+a b a b a b a b
+4 2 2 2 3 2 2 2
+4 2 2 2 4 2 2 2
+3 3 NULL NULL NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL NULL NULL
+SELECT t6.a,t6.b
+FROM t6;
+a b
+3 2
+6 2
+6 1
+SELECT t7.a,t7.b
+FROM t7;
+a b
+1 1
+2 2
+SELECT t6.a,t6.b,t7.a,t7.b
+FROM t6,t7;
+a b a b
+3 2 1 1
+3 2 2 2
+6 2 1 1
+6 2 2 2
+6 1 1 1
+6 1 2 2
+SELECT t8.a,t8.b
+FROM t8;
+a b
+0 2
+1 2
+EXPLAIN EXTENDED
+SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM (t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
+1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1
+SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM (t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10;
+a b a b a b
+3 2 2 2 0 2
+6 2 2 2 0 2
+6 1 2 2 0 2
+3 2 2 2 1 2
+6 2 2 2 1 2
+6 1 2 2 1 2
+3 2 1 1 NULL NULL
+6 2 1 1 NULL NULL
+6 1 1 1 NULL NULL
+SELECT t5.a,t5.b
+FROM t5;
+a b
+3 1
+2 2
+3 3
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+ON t6.b >= 2 AND t5.b=t7.b;
+a b a b a b a b
+2 2 3 2 2 2 0 2
+2 2 6 2 2 2 0 2
+2 2 3 2 2 2 1 2
+2 2 6 2 2 2 1 2
+3 1 3 2 1 1 NULL NULL
+3 1 6 2 1 1 NULL NULL
+3 3 NULL NULL NULL NULL NULL NULL
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+ON t6.b >= 2 AND t5.b=t7.b AND
+(t8.a < 1 OR t8.c IS NULL);
+a b a b a b a b
+2 2 3 2 2 2 0 2
+2 2 6 2 2 2 0 2
+3 1 3 2 1 1 NULL NULL
+3 1 6 2 1 1 NULL NULL
+3 3 NULL NULL NULL NULL NULL NULL
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+ON t6.b >= 2 AND t5.b=t7.b;
+a b a b a b a b a b a b a b
+4 2 1 2 3 2 2 2 3 2 2 2 0 2
+4 2 1 2 4 2 2 2 3 2 2 2 0 2
+4 2 1 2 3 2 2 2 6 2 2 2 0 2
+4 2 1 2 4 2 2 2 6 2 2 2 0 2
+4 2 1 2 3 2 2 2 3 2 2 2 1 2
+4 2 1 2 4 2 2 2 3 2 2 2 1 2
+4 2 1 2 3 2 2 2 6 2 2 2 1 2
+4 2 1 2 4 2 2 2 6 2 2 2 1 2
+4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL
+4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL
+4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+3 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+3 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+3 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+3 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+3 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+3 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+3 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+ON t6.b >= 2 AND t5.b=t7.b
+WHERE t2.a > 3 AND
+(t6.a < 6 OR t6.c IS NULL);
+a b a b a b a b a b a b a b
+4 2 1 2 3 2 2 2 3 2 2 2 0 2
+4 2 1 2 4 2 2 2 3 2 2 2 0 2
+4 2 1 2 3 2 2 2 3 2 2 2 1 2
+4 2 1 2 4 2 2 2 3 2 2 2 1 2
+4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+SELECT t1.a,t1.b
+FROM t1;
+a b
+1 3
+2 2
+3 2
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t1
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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);
+a b a b a b a b a b a b a b a b
+3 2 4 2 1 2 3 2 2 2 3 2 2 2 0 2
+3 2 4 2 1 2 4 2 2 2 3 2 2 2 0 2
+3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2
+3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2
+3 2 4 2 1 2 3 2 2 2 3 2 2 2 1 2
+3 2 4 2 1 2 4 2 2 2 3 2 2 2 1 2
+3 2 4 2 1 2 3 2 2 2 6 2 2 2 1 2
+3 2 4 2 1 2 4 2 2 2 6 2 2 2 1 2
+1 3 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+3 2 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+1 3 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+3 2 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+1 3 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL
+3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL
+1 3 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL
+3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL
+1 3 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+1 3 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+1 3 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+3 2 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+1 3 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+3 2 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+1 3 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+3 2 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+1 3 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+3 2 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+1 3 3 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+3 2 3 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+1 3 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+3 2 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+1 3 3 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+3 2 3 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+1 3 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+1 3 3 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+3 2 3 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+1 3 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t1
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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)
+WHERE (t2.a >= 4 OR t2.c IS NULL);
+a b a b a b a b a b a b a b a b
+3 2 4 2 1 2 3 2 2 2 3 2 2 2 0 2
+3 2 4 2 1 2 4 2 2 2 3 2 2 2 0 2
+3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2
+3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2
+3 2 4 2 1 2 3 2 2 2 3 2 2 2 1 2
+3 2 4 2 1 2 4 2 2 2 3 2 2 2 1 2
+3 2 4 2 1 2 3 2 2 2 6 2 2 2 1 2
+3 2 4 2 1 2 4 2 2 2 6 2 2 2 1 2
+1 3 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+3 2 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+1 3 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+3 2 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+1 3 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL
+3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL
+1 3 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL
+3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL
+1 3 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+1 3 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+1 3 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+3 2 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+1 3 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+1 3 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
+SELECT t0.a,t0.b
+FROM t0;
+a b
+1 1
+1 2
+2 2
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t0,t1
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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)
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL);
+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; 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 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 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 t8 ALL NULL NULL NULL NULL 2 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` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t0,t1
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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)
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL);
+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 3 2 2 2 0 2
+1 2 3 2 4 2 1 2 4 2 2 2 3 2 2 2 0 2
+1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2
+1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2
+1 2 3 2 4 2 1 2 3 2 2 2 3 2 2 2 1 2
+1 2 3 2 4 2 1 2 4 2 2 2 3 2 2 2 1 2
+1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 1 2
+1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 1 2
+1 2 3 2 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL
+1 2 3 2 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL
+1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL
+1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL
+1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL
+1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL
+1 2 3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2
+1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2
+1 2 3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2
+1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2
+1 2 3 2 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL
+1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL
+1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL
+1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
+EXPLAIN EXTENDED
+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
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) AND
+(t8.b=t9.b OR t8.c IS NULL) AND
+(t9.a=1);
+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; 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 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 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 t8 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`))) 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`)))
+SELECT t9.a,t9.b
+FROM t9;
+a b
+1 1
+1 2
+3 3
+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
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) 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 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 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 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
+1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2
+1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1
+1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 2
+1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1
+1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2
+SELECT t1.a,t1.b
+FROM t1;
+a b
+1 3
+2 2
+3 2
+SELECT t2.a,t2.b
+FROM t2;
+a b
+3 3
+4 2
+5 3
+SELECT t3.a,t3.b
+FROM t3;
+a b
+1 2
+2 2
+SELECT t2.a,t2.b,t3.a,t3.b
+FROM t2
+LEFT JOIN
+t3
+ON t2.b=t3.b;
+a b a b
+4 2 1 2
+4 2 2 2
+3 3 NULL NULL
+5 3 NULL NULL
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b
+FROM t1, t2
+LEFT JOIN
+t3
+ON t2.b=t3.b
+WHERE t1.a <= 2;
+a b a b a b
+1 3 4 2 1 2
+2 2 4 2 1 2
+1 3 4 2 2 2
+2 2 4 2 2 2
+1 3 3 3 NULL NULL
+2 2 3 3 NULL NULL
+1 3 5 3 NULL NULL
+2 2 5 3 NULL NULL
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b
+FROM t1, t3
+RIGHT JOIN
+t2
+ON t2.b=t3.b
+WHERE t1.a <= 2;
+a b a b a b
+1 3 4 2 1 2
+2 2 4 2 1 2
+1 3 4 2 2 2
+2 2 4 2 2 2
+1 3 3 3 NULL NULL
+2 2 3 3 NULL NULL
+1 3 5 3 NULL NULL
+2 2 5 3 NULL NULL
+SELECT t3.a,t3.b,t4.a,t4.b
+FROM t3,t4;
+a b a b
+1 2 3 2
+2 2 3 2
+1 2 4 2
+2 2 4 2
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+3 3 NULL NULL NULL NULL
+5 3 NULL NULL NULL NULL
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t1, t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b
+WHERE t1.a <= 2;
+a b a b a b a b
+1 3 4 2 1 2 3 2
+2 2 4 2 1 2 3 2
+1 3 4 2 1 2 4 2
+2 2 4 2 1 2 4 2
+1 3 3 3 NULL NULL NULL NULL
+2 2 3 3 NULL NULL NULL NULL
+1 3 5 3 NULL NULL NULL NULL
+2 2 5 3 NULL NULL NULL NULL
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t1, (t3, t4)
+RIGHT JOIN
+t2
+ON t3.a=1 AND t2.b=t4.b
+WHERE t1.a <= 2;
+a b a b a b a b
+1 3 4 2 1 2 3 2
+2 2 4 2 1 2 3 2
+1 3 4 2 1 2 4 2
+2 2 4 2 1 2 4 2
+1 3 3 3 NULL NULL NULL NULL
+2 2 3 3 NULL NULL NULL NULL
+1 3 5 3 NULL NULL NULL NULL
+2 2 5 3 NULL NULL NULL NULL
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t1, (t3, t4)
+RIGHT JOIN
+t2
+ON t3.a=1 AND t2.b=t4.b
+WHERE t1.a <= 2;
+a b a b a b a b
+1 3 4 2 1 2 3 2
+2 2 4 2 1 2 3 2
+1 3 4 2 1 2 4 2
+2 2 4 2 1 2 4 2
+1 3 3 3 NULL NULL NULL NULL
+2 2 3 3 NULL NULL NULL NULL
+1 3 5 3 NULL NULL NULL NULL
+2 2 5 3 NULL NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM t1, (t3, t4)
+RIGHT JOIN
+t2
+ON t3.a=1 AND t2.b=t4.b
+WHERE t1.a <= 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL 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`))) where (`test`.`t1`.`a` <= 2)
+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;
+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)
+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
+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;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+4 2 1 2 3 2
+4 2 1 2 4 2
+4 2 1 2 3 2
+4 2 1 2 4 2
+NULL NULL 2 2 3 2
+NULL NULL 2 2 4 2
+EXPLAIN EXTENDED
+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
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) AND
+(t8.b=t9.b OR t8.c IS NULL) AND
+(t9.a=1);
+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; 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 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 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 t8 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`))) 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`)))
+CREATE INDEX idx_b ON t4(b);
+CREATE INDEX idx_b ON t5(b);
+EXPLAIN EXTENDED
+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
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) AND
+(t8.b=t9.b OR t8.c IS NULL) AND
+(t9.a=1);
+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; 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)
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 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 t8 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`))))) 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`)))
+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,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+FROM t0,t1
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) AND
+(t8.b=t9.b OR t8.c IS NULL) AND
+(t9.a=1);
+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; 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)
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 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 t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA 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`)))) 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`)))
+CREATE INDEX idx_b ON t1(b);
+CREATE INDEX idx_a ON t0(a);
+EXPLAIN EXTENDED
+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
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) AND
+(t8.b=t9.b OR t8.c IS NULL) AND
+(t9.a=1);
+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)
+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 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 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 t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA 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`)))) 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`)))
+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
+LEFT JOIN
+(
+t2
+LEFT JOIN
+(t3, t4)
+ON t3.a=1 AND t2.b=t4.b,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+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),
+t9
+WHERE t0.a=1 AND
+t0.b=t1.b AND
+(t2.a >= 4 OR t2.c IS NULL) AND
+(t3.a < 5 OR t3.c IS NULL) AND
+(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+(t5.a >=2 OR t5.c IS NULL) AND
+(t6.a >=4 OR t6.c IS NULL) AND
+(t7.a <= 2 OR t7.c IS NULL) AND
+(t8.a < 1 OR t8.c IS NULL) 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 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 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 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
+1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2
+1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1
+1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 2
+1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1
+1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2
+SELECT t2.a,t2.b
+FROM t2;
+a b
+3 3
+4 2
+5 3
+SELECT t3.a,t3.b
+FROM t3;
+a b
+1 2
+2 2
+SELECT t2.a,t2.b,t3.a,t3.b
+FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
+a b a b
+4 2 1 2
+4 2 2 2
+5 3 NULL NULL
+SELECT t2.a,t2.b,t3.a,t3.b
+FROM t2 LEFT JOIN (t3) ON t2.b=t3.b
+WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
+a b a b
+4 2 1 2
+4 2 2 2
+5 3 NULL NULL
+ALTER TABLE t3
+CHANGE COLUMN a a1 int,
+CHANGE COLUMN c c1 int;
+SELECT t2.a,t2.b,t3.a1,t3.b
+FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t2.a = 4 OR (t2.a > 4 AND t3.a1 IS NULL);
+a b a1 b
+4 2 1 2
+4 2 2 2
+5 3 NULL NULL
+SELECT t2.a,t2.b,t3.a1,t3.b
+FROM t2 NATURAL LEFT JOIN t3
+WHERE t2.a = 4 OR (t2.a > 4 AND t3.a1 IS NULL);
+a b a1 b
+4 2 1 2
+4 2 2 2
+5 3 NULL NULL
+DROP TABLE t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (2);
+INSERT INTO t1 VALUES (2);
+SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.a=t3.a;
+a a a
+2 2 2
+1 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a;
+a a a
+2 2 2
+1 NULL NULL
+DELETE FROM t1 WHERE a=2;
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a;
+a a a
+1 NULL NULL
+DELETE FROM t2;
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a;
+a a a
+1 NULL NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(a int, key (a));
+CREATE TABLE t2(b int, key (b));
+CREATE TABLE t3(c int, key (c));
+INSERT INTO t1 VALUES (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
+(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
+INSERT INTO t2 VALUES (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
+(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
+INSERT INTO t3 VALUES (0), (1), (2), (3), (4), (5);
+EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 Using index
+1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
+EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 Using index
+1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
+SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+a b c
+NULL 0 0
+NULL 1 1
+NULL 2 2
+0 0 0
+0 1 1
+0 2 2
+1 0 0
+1 1 1
+1 2 2
+2 0 0
+2 1 1
+2 2 2
+3 0 0
+3 1 1
+3 2 2
+4 0 0
+4 1 1
+4 2 2
+5 0 0
+5 1 1
+5 2 2
+6 0 0
+6 1 1
+6 2 2
+7 0 0
+7 1 1
+7 2 2
+8 0 0
+8 1 1
+8 2 2
+9 0 0
+9 1 1
+9 2 2
+10 0 0
+10 1 1
+10 2 2
+11 0 0
+11 1 1
+11 2 2
+12 0 0
+12 1 1
+12 2 2
+13 0 0
+13 1 1
+13 2 2
+14 0 0
+14 1 1
+14 2 2
+15 0 0
+15 1 1
+15 2 2
+16 0 0
+16 1 1
+16 2 2
+17 0 0
+17 1 1
+17 2 2
+18 0 0
+18 1 1
+18 2 2
+19 0 0
+19 1 1
+19 2 2
+DELETE FROM t3;
+EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 Using index
+1 SIMPLE t3 index c c 5 NULL 0 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
+SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+a b c
+NULL NULL NULL
+0 NULL NULL
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 NULL NULL
+7 NULL NULL
+8 NULL NULL
+9 NULL NULL
+10 NULL NULL
+11 NULL NULL
+12 NULL NULL
+13 NULL NULL
+14 NULL NULL
+15 NULL NULL
+16 NULL NULL
+17 NULL NULL
+18 NULL NULL
+19 NULL NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c11 int);
+CREATE TABLE t2 (c21 int);
+CREATE TABLE t3 (c31 int);
+INSERT INTO t1 VALUES (4), (5);
+SELECT * FROM t1 LEFT JOIN t2 ON c11=c21;
+c11 c21
+4 NULL
+5 NULL
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON c11=c21;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
+c11 c21 c31
+4 NULL NULL
+5 NULL NULL
+EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL);
+INSERT INTO t1 VALUES (23, 2340), (26, 9900);
+CREATE TABLE t2 (goods int(12), name varchar(50), shop char(2));
+INSERT INTO t2 VALUES (23, 'as300', 'fr'), (26, 'as600', 'fr');
+create table t3 (groupid int(12) NOT NULL, goodsid int(12) NOT NULL);
+INSERT INTO t3 VALUES (3,23), (6,26);
+CREATE TABLE t4 (groupid int(12));
+INSERT INTO t4 VALUES (1), (2), (3), (4), (5), (6);
+SELECT * FROM
+(SELECT DISTINCT gl.groupid, gp.price
+FROM t4 gl
+LEFT JOIN
+(t3 g INNER JOIN t2 p ON g.goodsid = p.goods
+INNER JOIN t1 gp ON p.goods = gp.goods)
+ON gl.groupid = g.groupid and p.shop = 'fr') t;
+groupid price
+3 2340
+6 9900
+1 NULL
+2 NULL
+4 NULL
+5 NULL
+CREATE VIEW v1 AS
+SELECT g.groupid groupid, p.goods goods,
+p.name name, p.shop shop,
+gp.price price
+FROM t3 g INNER JOIN t2 p ON g.goodsid = p.goods
+INNER JOIN t1 gp on p.goods = gp.goods;
+CREATE VIEW v2 AS
+SELECT DISTINCT g.groupid, fr.price
+FROM t4 g
+LEFT JOIN
+v1 fr on g.groupid = fr.groupid and fr.shop = 'fr';
+SELECT * FROM v2;
+groupid price
+3 2340
+6 9900
+1 NULL
+2 NULL
+4 NULL
+5 NULL
+SELECT * FROM
+(SELECT DISTINCT g.groupid, fr.price
+FROM t4 g
+LEFT JOIN
+v1 fr on g.groupid = fr.groupid and fr.shop = 'fr') t;
+groupid price
+3 2340
+6 9900
+1 NULL
+2 NULL
+4 NULL
+5 NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1(a int);
+CREATE TABLE t2(b int);
+CREATE TABLE t3(c int, d int);
+CREATE TABLE t4(d int);
+CREATE TABLE t5(e int, f int);
+CREATE TABLE t6(f int);
+CREATE VIEW v1 AS
+SELECT e FROM t5 JOIN t6 ON t5.e=t6.f;
+CREATE VIEW v2 AS
+SELECT e FROM t5 NATURAL JOIN t6;
+SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d);
+a
+SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d);
+ERROR 42S22: Unknown column 't1.x' in 'field list'
+SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4;
+a
+SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4;
+ERROR 42S22: Unknown column 't1.x' in 'field list'
+SELECT v1.e FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+e
+SELECT v1.x FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+ERROR 42S22: Unknown column 'v1.x' in 'field list'
+SELECT v2.e FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+e
+SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+ERROR 42S22: Unknown column 'v2.x' in 'field list'
+DROP VIEW v1, v2;
+DROP TABLE t1, t2, t3, t4, t5, t6;
+create table t1 (id1 int(11) not null);
+insert into t1 values (1),(2);
+create table t2 (id2 int(11) not null);
+insert into t2 values (1),(2),(3),(4);
+create table t3 (id3 char(16) not null);
+insert into t3 values ('100');
+create table t4 (id2 int(11) not null, id3 char(16));
+create table t5 (id1 int(11) not null, key (id1));
+insert into t5 values (1),(2),(1);
+create view v1 as
+select t4.id3 from t4 join t2 on t4.id2 = t2.id2;
+select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3);
+id1
+1
+2
+drop view v1;
+drop table t1, t2, t3, t4, t5;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3);
+create table t1(a int);
+insert into t1 select A.a + 10*(B.a) from t0 A, t0 B;
+create table t2 (a int, b int);
+insert into t2 values (1,1), (2,2), (3,3);
+create table t3(a int, b int, filler char(200), key(a));
+insert into t3 select a,a,'filler' from t1;
+insert into t3 select a,a,'filler' from t1;
+create table t4 like t3;
+insert into t4 select * from t3;
+insert into t4 select * from t3;
+create table t5 like t4;
+insert into t5 select * from t4;
+insert into t5 select * from t4;
+create table t6 like t5;
+insert into t6 select * from t5;
+insert into t6 select * from t5;
+create table t7 like t6;
+insert into t7 select * from t6;
+insert into t7 select * from t6;
+explain select * from t4 join
+t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer (flat, BKA join)
+1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join)
+1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition(BKA); Using join buffer (incremental, BKA join)
+explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
+join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using index condition(BKA); Using join buffer (flat, BKA join)
+1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer (incremental, BKA join)
+1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join)
+1 SIMPLE t5 ref a a 5 test.t2.b X Using where; Using join buffer (incremental, BKA join)
+1 SIMPLE t7 ref a a 5 test.t5.b X Using join buffer (incremental, BKA join)
+explain select * from t2 left join
+(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
+join t5 on t5.a=t3.b) on t3.a=t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer (flat, BKA join)
+1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join)
+1 SIMPLE t4 ref a a 5 test.t5.a X Using where; Using join buffer (incremental, BKA join)
+1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join)
+drop table t0, t1, t2, t3, t4, t5, t6, t7;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, filler char(100), key(a));
+insert into t2 select A.a + 10*B.a, '' from t1 A, t1 B;
+create table t3 like t2;
+insert into t3 select * from t2;
+explain select * from t1 left join
+(t2 left join t3 on (t2.a = t3.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 10
+1 SIMPLE t2 ref a a 5 test.t1.a 1 Using where; Using join buffer (flat, BKA join)
+1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where; Using join buffer (incremental, BKA join)
+drop table t1, t2, t3;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10));
+CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10));
+CREATE TABLE t3 (cid int NOT NULL PRIMARY KEY,
+id int NOT NULL,
+pid int NOT NULL);
+INSERT INTO t1 VALUES (1, 'A'), (3, 'C');
+INSERT INTO t2 VALUES (1, 'A'), (3, 'C');
+INSERT INTO t3 VALUES (1, 1, 1), (3, 3, 3);
+SELECT * FROM t1 p LEFT JOIN (t3 JOIN t1)
+ON (t1.id=t3.id AND t1.type='B' AND p.id=t3.id)
+LEFT JOIN t2 ON (t3.pid=t2.pid)
+WHERE p.id=1;
+id type cid id pid id type pid type
+1 A NULL NULL NULL NULL NULL NULL NULL
+CREATE VIEW v1 AS
+SELECT t3.* FROM t3 JOIN t1 ON t1.id=t3.id AND t1.type='B';
+SELECT * FROM t1 p LEFT JOIN v1 ON p.id=v1.id
+LEFT JOIN t2 ON v1.pid=t2.pid
+WHERE p.id=1;
+id type cid id pid pid type
+1 A NULL NULL NULL NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id1 int PRIMARY KEY, id2 int);
+CREATE TABLE t2 (id1 int PRIMARY KEY, id2 int);
+CREATE TABLE t3 (id1 int PRIMARY KEY, id2 int);
+CREATE TABLE t4 (id1 int PRIMARY KEY, id2 int);
+CREATE TABLE t5 (id1 int PRIMARY KEY, id2 int);
+SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
+FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
+LEFT OUTER JOIN
+(t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
+ON t3.id2 IS NOT NULL
+WHERE t1.id1=2;
+id ngroupbynsa
+PREPARE stmt FROM
+"SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
+ FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
+ LEFT OUTER JOIN
+ (t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
+ ON t3.id2 IS NOT NULL
+ WHERE t1.id1=2";
+EXECUTE stmt;
+id ngroupbynsa
+EXECUTE stmt;
+id ngroupbynsa
+EXECUTE stmt;
+id ngroupbynsa
+EXECUTE stmt;
+id ngroupbynsa
+INSERT INTO t1 VALUES (1,1), (2,1), (3,2);
+INSERT INTO t2 VALUES (2,1), (3,2), (4,3);
+INSERT INTO t3 VALUES (1,1), (3,2), (2,NULL);
+INSERT INTO t4 VALUES (1,1), (2,1), (3,3);
+INSERT INTO t5 VALUES (1,1), (2,2), (3,3), (4,3);
+EXECUTE stmt;
+id ngroupbynsa
+2 1
+2 1
+EXECUTE stmt;
+id ngroupbynsa
+2 1
+2 1
+EXECUTE stmt;
+id ngroupbynsa
+2 1
+2 1
+EXECUTE stmt;
+id ngroupbynsa
+2 1
+2 1
+SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
+FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
+LEFT OUTER JOIN
+(t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
+ON t3.id2 IS NOT NULL
+WHERE t1.id1=2;
+id ngroupbynsa
+2 1
+2 1
+DROP TABLE t1,t2,t3,t4,t5;
+CREATE TABLE t1 (
+id int NOT NULL PRIMARY KEY,
+ct int DEFAULT NULL,
+pc int DEFAULT NULL,
+INDEX idx_ct (ct),
+INDEX idx_pc (pc)
+);
+INSERT INTO t1 VALUES
+(1,NULL,NULL),(2,NULL,NULL),(3,NULL,NULL),(4,NULL,NULL),(5,NULL,NULL);
+CREATE TABLE t2 (
+id int NOT NULL PRIMARY KEY,
+sr int NOT NULL,
+nm varchar(255) NOT NULL,
+INDEX idx_sr (sr)
+);
+INSERT INTO t2 VALUES
+(2441905,4308,'LesAbymes'),(2441906,4308,'Anse-Bertrand');
+CREATE TABLE t3 (
+id int NOT NULL PRIMARY KEY,
+ct int NOT NULL,
+ln int NOT NULL,
+INDEX idx_ct (ct),
+INDEX idx_ln (ln)
+);
+CREATE TABLE t4 (
+id int NOT NULL PRIMARY KEY,
+nm varchar(255) NOT NULL
+);
+INSERT INTO t4 VALUES (4308,'Guadeloupe'),(4309,'Martinique');
+SELECT t1.*
+FROM t1 LEFT JOIN
+(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id
+WHERE t1.id='5';
+id ct pc
+5 NULL NULL
+SELECT t1.*, t4.nm
+FROM t1 LEFT JOIN
+(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id
+LEFT JOIN t4 ON t2.sr=t4.id
+WHERE t1.id='5';
+id ct pc nm
+5 NULL NULL NULL
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, c INT);
+CREATE TABLE t4 (a INT, c INT);
+CREATE TABLE t5 (a INT, c INT);
+SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
+LEFT JOIN t5 USING (a)) USING (a);
+b
+SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
+LEFT JOIN t5 USING (a)) USING (a);
+ERROR 23000: Column 'c' in field list is ambiguous
+SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
+JOIN t5 USING (a)) USING (a);
+b
+SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
+JOIN t5 USING (a)) USING (a);
+ERROR 23000: Column 'c' in field list is ambiguous
+DROP TABLE t1,t2,t3,t4,t5;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, b INT);
+CREATE TABLE t3 (a INT, b INT);
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t2 VALUES (1,1);
+INSERT INTO t3 VALUES (1,1);
+SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a);
+ERROR 23000: Column 'a' in from clause is ambiguous
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+carrier char(2) default NULL,
+id int NOT NULL auto_increment PRIMARY KEY
+);
+INSERT INTO t1 VALUES
+('CO',235371754),('CO',235376554),('CO',235376884),('CO',235377874),
+('CO',231060394),('CO',231059224),('CO',231059314),('CO',231060484),
+('CO',231060274),('CO',231060124),('CO',231060244),('CO',231058594),
+('CO',231058924),('CO',231058504),('CO',231059344),('CO',231060424),
+('CO',231059554),('CO',231060304),('CO',231059644),('CO',231059464),
+('CO',231059764),('CO',231058294),('CO',231058624),('CO',231058864),
+('CO',231059374),('CO',231059584),('CO',231059734),('CO',231059014),
+('CO',231059854),('CO',231059494),('CO',231059794),('CO',231058534),
+('CO',231058324),('CO',231058684),('CO',231059524),('CO',231059974);
+CREATE TABLE t2 (
+scan_date date default NULL,
+package_id int default NULL,
+INDEX scan_date(scan_date),
+INDEX package_id(package_id)
+);
+INSERT INTO t2 VALUES
+('2008-12-29',231062944),('2008-12-29',231065764),('2008-12-29',231066124),
+('2008-12-29',231060094),('2008-12-29',231061054),('2008-12-29',231065644),
+('2008-12-29',231064384),('2008-12-29',231064444),('2008-12-29',231073774),
+('2008-12-29',231058594),('2008-12-29',231059374),('2008-12-29',231066004),
+('2008-12-29',231068494),('2008-12-29',231070174),('2008-12-29',231071884),
+('2008-12-29',231063274),('2008-12-29',231063754),('2008-12-29',231064144),
+('2008-12-29',231069424),('2008-12-29',231073714),('2008-12-29',231058414),
+('2008-12-29',231060994),('2008-12-29',231069154),('2008-12-29',231068614),
+('2008-12-29',231071464),('2008-12-29',231074014),('2008-12-29',231059614),
+('2008-12-29',231059074),('2008-12-29',231059464),('2008-12-29',231069094),
+('2008-12-29',231067294),('2008-12-29',231070144),('2008-12-29',231073804),
+('2008-12-29',231072634),('2008-12-29',231058294),('2008-12-29',231065344),
+('2008-12-29',231066094),('2008-12-29',231069034),('2008-12-29',231058594),
+('2008-12-29',231059854),('2008-12-29',231059884),('2008-12-29',231059914),
+('2008-12-29',231063664),('2008-12-29',231063814),('2008-12-29',231063904);
+CREATE TABLE t3 (
+package_id int default NULL,
+INDEX package_id(package_id)
+);
+INSERT INTO t3 VALUES
+(231058294),(231058324),(231058354),(231058384),(231058414),(231058444),
+(231058474),(231058504),(231058534),(231058564),(231058594),(231058624),
+(231058684),(231058744),(231058804),(231058864),(231058924),(231058954),
+(231059014),(231059074),(231059104),(231059134),(231059164),(231059194),
+(231059224),(231059254),(231059284),(231059314),(231059344),(231059374),
+(231059404),(231059434),(231059464),(231059494),(231059524),(231059554),
+(231059584),(231059614),(231059644),(231059674),(231059704),(231059734),
+(231059764),(231059794),(231059824),(231059854),(231059884),(231059914),
+(231059944),(231059974),(231060004),(231060034),(231060064),(231060094),
+(231060124),(231060154),(231060184),(231060214),(231060244),(231060274),
+(231060304),(231060334),(231060364),(231060394),(231060424),(231060454),
+(231060484),(231060514),(231060544),(231060574),(231060604),(231060634),
+(231060664),(231060694),(231060724),(231060754),(231060784),(231060814),
+(231060844),(231060874),(231060904),(231060934),(231060964),(231060994),
+(231061024),(231061054),(231061084),(231061144),(231061174),(231061204),
+(231061234),(231061294),(231061354),(231061384),(231061414),(231061474),
+(231061564),(231061594),(231061624),(231061684),(231061714),(231061774),
+(231061804),(231061894),(231061984),(231062074),(231062134),(231062224),
+(231062254),(231062314),(231062374),(231062434),(231062494),(231062554),
+(231062584),(231062614),(231062644),(231062704),(231062734),(231062794),
+(231062854),(231062884),(231062944),(231063004),(231063034),(231063064),
+(231063124),(231063154),(231063184),(231063214),(231063274),(231063334),
+(231063394),(231063424),(231063454),(231063514),(231063574),(231063664);
+CREATE TABLE t4 (
+carrier char(2) NOT NULL default '' PRIMARY KEY,
+id int(11) default NULL,
+INDEX id(id)
+);
+INSERT INTO t4 VALUES
+('99',6),('SK',456),('UA',486),('AI',1081),('OS',1111),('VS',1510);
+CREATE TABLE t5 (
+carrier_id int default NULL,
+INDEX carrier_id(carrier_id)
+);
+INSERT INTO t5 VALUES
+(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),
+(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),
+(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),
+(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),
+(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),
+(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(456),(456),(456),
+(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),
+(456),(486),(1081),(1111),(1111),(1111),(1111),(1510);
+SELECT COUNT(*)
+FROM((t2 JOIN t1 ON t2.package_id = t1.id)
+JOIN t3 ON t3.package_id = t1.id);
+COUNT(*)
+6
+EXPLAIN
+SELECT COUNT(*)
+FROM ((t2 JOIN t1 ON t2.package_id = t1.id)
+JOIN t3 ON t3.package_id = t1.id)
+LEFT JOIN
+(t5 JOIN t4 ON t5.carrier_id = t4.id)
+ON t4.carrier = t1.carrier;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index package_id package_id 5 NULL 45 Using where; Using index
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 Using join buffer (flat, BKA join)
+1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1 Using where
+1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index
+1 SIMPLE t3 ref package_id package_id 5 test.t1.id 1 Using where; Using index
+SELECT COUNT(*)
+FROM ((t2 JOIN t1 ON t2.package_id = t1.id)
+JOIN t3 ON t3.package_id = t1.id)
+LEFT JOIN
+(t5 JOIN t4 ON t5.carrier_id = t4.id)
+ON t4.carrier = t1.carrier;
+COUNT(*)
+6
+DROP TABLE t1,t2,t3,t4,t5;
+CREATE TABLE t1 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int DEFAULT NULL,
+KEY idx(a)
+);
+CREATE TABLE t2 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int DEFAULT NULL,
+KEY idx(a)
+);
+CREATE TABLE t3 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int DEFAULT NULL,
+KEY idx(a)
+);
+INSERT INTO t1 VALUES
+(1,2), (2,7), (3,5), (4,7), (5,5), (6,NULL), (7,NULL), (8,9);
+INSERT INTO t2 VALUES
+(1,NULL), (4,2), (5,2), (3,4), (2,8);
+INSERT INTO t3 VALUES
+(1,9), (2,2), (3,5), (4,2), (5,7), (6,0), (7,5);
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a;
+pk a pk a pk a
+1 2 4 2 2 2
+1 2 5 2 2 2
+1 2 4 2 4 2
+1 2 5 2 4 2
+2 7 NULL NULL NULL NULL
+3 5 NULL NULL NULL NULL
+4 7 NULL NULL NULL NULL
+5 5 NULL NULL NULL NULL
+6 NULL NULL NULL NULL NULL
+7 NULL NULL NULL NULL NULL
+8 9 NULL NULL NULL NULL
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a
+WHERE t2.pk IS NULL;
+pk a pk a pk a
+2 7 NULL NULL NULL NULL
+3 5 NULL NULL NULL NULL
+4 7 NULL NULL NULL NULL
+5 5 NULL NULL NULL NULL
+6 NULL NULL NULL NULL NULL
+7 NULL NULL NULL NULL NULL
+8 9 NULL NULL NULL NULL
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a
+WHERE t3.pk IS NULL;
+pk a pk a pk a
+2 7 NULL NULL NULL NULL
+3 5 NULL NULL NULL NULL
+4 7 NULL NULL NULL NULL
+5 5 NULL NULL NULL NULL
+6 NULL NULL NULL NULL NULL
+7 NULL NULL NULL NULL NULL
+8 9 NULL NULL NULL NULL
+DROP TABLE t1, t2, t3;
+End of 5.0 tests
+CREATE TABLE t5 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+CREATE TABLE t6 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+CREATE TABLE t7 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+CREATE TABLE t8 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+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);
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+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);
+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)
+1 SIMPLE t6 ALL b_i NULL NULL NULL 3 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)
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+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);
+a b a b a b a b
+2 2 1 2 2 2 1 2
+2 2 3 2 2 2 1 2
+1 1 1 2 1 1 NULL NULL
+1 1 3 2 1 1 NULL NULL
+3 3 NULL NULL NULL NULL NULL NULL
+DELETE FROM t5;
+DELETE FROM t6;
+DELETE FROM t7;
+DELETE FROM t8;
+INSERT INTO t5 VALUES (1,3,0), (3,2,0);
+INSERT INTO t6 VALUES (3,3,0);
+INSERT INTO t7 VALUES (1,2,0);
+INSERT INTO t8 VALUES (1,1,0);
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5 LEFT JOIN
+(t6 LEFT JOIN t7 ON t7.a=1, t8)
+ON (t5.b=t8.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2
+1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join)
+1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5 LEFT JOIN
+(t6 LEFT JOIN t7 ON t7.a=1, t8)
+ON (t5.b=t8.b);
+a b a b a b a b
+1 3 NULL NULL NULL NULL NULL NULL
+3 2 NULL NULL NULL NULL NULL NULL
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5 LEFT JOIN
+(t6 LEFT JOIN t7 ON t7.b=2, t8)
+ON (t5.b=t8.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2
+1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t7 ref b_i b_i 5 const 0 Using join buffer (incremental, BKA join)
+1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5 LEFT JOIN
+(t6 LEFT JOIN t7 ON t7.b=2, t8)
+ON (t5.b=t8.b);
+a b a b a b a b
+1 3 NULL NULL NULL NULL NULL NULL
+3 2 NULL NULL NULL NULL NULL NULL
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5 LEFT JOIN
+(t8, t6 LEFT JOIN t7 ON t7.a=1)
+ON (t5.b=t8.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2
+1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
+1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join)
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5 LEFT JOIN
+(t8, t6 LEFT JOIN t7 ON t7.a=1)
+ON (t5.b=t8.b);
+a b a b a b a b
+1 3 NULL NULL NULL NULL NULL NULL
+3 2 NULL NULL NULL NULL NULL NULL
+DROP TABLE t5,t6,t7,t8;
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index aafb5dd8635..691bedbe428 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -416,10 +416,10 @@ n m o n m o
select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
t1.m = t2.m where t1.n = 1 order by t1.o;
n m o n m o
+1 2 11 1 2 3
1 2 7 1 2 3
1 2 9 1 2 3
1 3 9 NULL NULL NULL
-1 2 11 1 2 3
drop table t1,t2;
CREATE TABLE t1 (id1 INT NOT NULL PRIMARY KEY, dat1 CHAR(1), id2 INT);
INSERT INTO t1 VALUES (1,'a',1);
@@ -630,7 +630,7 @@ insert into t2 values (10,1),(20,2),(30,3);
explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index
-1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using index
+1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using where; Using index
select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID
10 1 NULL
@@ -688,8 +688,8 @@ a1 a2 b1 b2 c1 c2
explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
drop table t1, t2, t3;
create table t1 (
a int(11),
@@ -859,14 +859,14 @@ a1 a2
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON a1=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
a1 a2 a3
1 NULL NULL
EXPLAIN SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
a0 a1 a2 a3
@@ -875,7 +875,7 @@ EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 system PRIMARY NULL NULL NULL 1
1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
INSERT INTO t0 VALUES (0);
INSERT INTO t1 VALUES (0);
@@ -886,7 +886,7 @@ EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 const PRIMARY PRIMARY 4 const 1 Using index
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
drop table t1,t2;
create table t1 (a int, b int);
@@ -1268,7 +1268,7 @@ FROM t1 LEFT JOIN t2 USING( a )
GROUP BY t1.a WITH ROLLUP;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
-1 SIMPLE t2 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where
SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
FROM t1 LEFT JOIN t2 USING( a )
GROUP BY t1.a WITH ROLLUP;
@@ -1328,14 +1328,14 @@ RIGHT OUTER JOIN t1 tt1 ON 1
STRAIGHT_JOIN t1 tt9 ON 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tt1 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt2 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt3 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt4 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt5 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt6 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt7 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt8 ALL NULL NULL NULL NULL 2
-1 SIMPLE tt9 ALL NULL NULL NULL NULL 2 Using join buffer
+1 SIMPLE tt2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt4 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt5 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt6 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt7 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt8 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE tt9 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SET optimizer_search_depth = DEFAULT;
DROP TABLE t1;
#
@@ -1354,8 +1354,8 @@ EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1
RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE TA2 ALL NULL NULL NULL NULL 20 Using where
-1 SIMPLE TA3 ALL NULL NULL NULL NULL 20 Using join buffer
-1 SIMPLE TA1 ALL NULL NULL NULL NULL 2
+1 SIMPLE TA3 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 SIMPLE TA1 ALL NULL NULL NULL NULL 2 Using where
DROP TABLE t1, t2;
#
# Bug#48971 Segfault in add_found_match_trig_cond () at sql_select.cc:5990
@@ -1372,11 +1372,11 @@ RIGHT JOIN t1 AS jt6 ON jt6.f1
ON 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using index
+1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
+1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using index
+1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
+1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
Warnings:
Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1))) on(1) where 1
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
@@ -1389,11 +1389,11 @@ RIGHT JOIN t1 AS jt6 ON jt6.f1
ON 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using index
+1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using index
-1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using index
+1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
+1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
+1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
Warnings:
Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
DROP TABLE t1;
@@ -1438,7 +1438,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
@@ -1508,6 +1508,7 @@ Handler_read_prev 0
Handler_read_rnd 0
Handler_read_rnd_next 1048581
drop table t1,t2,t3;
+#
# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
#
CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1));
diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result
index e8a2d6f668b..56e557ec881 100644
--- a/mysql-test/r/join_outer_innodb.result
+++ b/mysql-test/r/join_outer_innodb.result
@@ -9,7 +9,7 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
-1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
+1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using index
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
new file mode 100644
index 00000000000..d4fd08868a8
--- /dev/null
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -0,0 +1,1553 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+drop table if exists t0,t1,t2,t3,t4,t5;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a bigint(20) unsigned default NULL,
+c char(10) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b'),(2,3,'c'),(3,4,'E'),(3,5,'C'),(3,6,'D'),(NULL,NULL,'');
+create table t2 (id int, a bigint unsigned not null, c char(10), d int, primary key (a));
+insert into t2 values (1,1,"a",1),(3,4,"A",4),(3,5,"B",5),(3,6,"C",6),(4,7,"D",7);
+select t1.*,t2.* from t1 JOIN t2 where t1.a=t2.a;
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c;
+grp a c id a c d
+NULL NULL NULL NULL NULL NULL
+1 1 a 1 1 a 1
+2 2 b NULL NULL NULL NULL
+2 3 c NULL NULL NULL NULL
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) };
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+NULL NULL NULL 4 7 D 7
+select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2;
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+NULL NULL NULL 4 7 D 7
+select t1.*,t2.* from t1 left join t2 using (a);
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+2 2 b NULL NULL NULL NULL
+2 3 c NULL NULL NULL NULL
+NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 using (a) where t1.a=t2.a;
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 using (a,c);
+grp a c id a c d
+1 1 a 1 1 a 1
+2 2 b NULL NULL NULL NULL
+2 3 c NULL NULL NULL NULL
+3 4 E NULL NULL NULL NULL
+3 5 C NULL NULL NULL NULL
+3 6 D NULL NULL NULL NULL
+NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 using (c);
+grp a c id a c d
+1 1 a 1 1 a 1
+1 1 a 3 4 A 4
+2 2 b 3 5 B 5
+2 3 c 3 6 C 6
+3 5 C 3 6 C 6
+3 6 D 4 7 D 7
+3 4 E NULL NULL NULL NULL
+NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 natural left outer join t2;
+grp a c id a c d
+1 1 a 1 1 a 1
+2 2 b NULL NULL NULL NULL
+2 3 c NULL NULL NULL NULL
+3 4 E NULL NULL NULL NULL
+3 5 C NULL NULL NULL NULL
+3 6 D NULL NULL NULL NULL
+NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id=3;
+grp a c id a c d
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id is null;
+grp a c id a c d
+2 2 b NULL NULL NULL NULL
+2 3 c NULL NULL NULL NULL
+NULL NULL NULL NULL NULL NULL
+explain select t1.*,t2.* from t1,t2 where t1.a=t2.a and isnull(t2.a)=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1;
+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 eq_ref PRIMARY PRIMARY 8 test.t1.a 1 Using where; Using join buffer (flat, BKA join)
+select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
+grp a c id a c d a
+1 1 a 1 1 a 1 1
+3 4 E 3 4 A 4 4
+3 5 C 3 5 B 5 5
+3 6 D 3 6 C 6 6
+2 2 b NULL NULL NULL NULL NULL
+2 3 c NULL NULL NULL NULL NULL
+NULL NULL NULL NULL NULL NULL NULL
+explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+ERROR 42S22: Unknown column 't3.a' in 'on clause'
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+ERROR 42S22: Unknown column 't3.a' in 'on clause'
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
+ERROR 42S22: Unknown column 't3.a' in 'on clause'
+select t1.*,t2.* from t1 inner join t2 using (a);
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+select t1.*,t2.* from t1 inner join t2 on (t1.a=t2.a);
+grp a c id a c d
+1 1 a 1 1 a 1
+3 4 E 3 4 A 4
+3 5 C 3 5 B 5
+3 6 D 3 6 C 6
+select t1.*,t2.* from t1 natural join t2;
+grp a c id a c d
+1 1 a 1 1 a 1
+drop table t1,t2;
+CREATE TABLE t1 (
+usr_id INT unsigned NOT NULL,
+uniq_id INT unsigned NOT NULL AUTO_INCREMENT,
+start_num INT unsigned NOT NULL DEFAULT 1,
+increment INT unsigned NOT NULL DEFAULT 1,
+PRIMARY KEY (uniq_id),
+INDEX usr_uniq_idx (usr_id, uniq_id),
+INDEX uniq_usr_idx (uniq_id, usr_id)
+);
+CREATE TABLE t2 (
+id INT unsigned NOT NULL DEFAULT 0,
+usr2_id INT unsigned NOT NULL DEFAULT 0,
+max INT unsigned NOT NULL DEFAULT 0,
+c_amount INT unsigned NOT NULL DEFAULT 0,
+d_max INT unsigned NOT NULL DEFAULT 0,
+d_num INT unsigned NOT NULL DEFAULT 0,
+orig_time INT unsigned NOT NULL DEFAULT 0,
+c_time INT unsigned NOT NULL DEFAULT 0,
+active ENUM ("no","yes") NOT NULL,
+PRIMARY KEY (id,usr2_id),
+INDEX id_idx (id),
+INDEX usr2_idx (usr2_id)
+);
+INSERT INTO t1 VALUES (3,NULL,0,50),(3,NULL,0,200),(3,NULL,0,25),(3,NULL,0,84676),(3,NULL,0,235),(3,NULL,0,10),(3,NULL,0,3098),(3,NULL,0,2947),(3,NULL,0,8987),(3,NULL,0,8347654),(3,NULL,0,20398),(3,NULL,0,8976),(3,NULL,0,500),(3,NULL,0,198);
+SELECT t1.usr_id,t1.uniq_id,t1.increment,
+t2.usr2_id,t2.c_amount,t2.max
+FROM t1
+LEFT JOIN t2 ON t2.id = t1.uniq_id
+WHERE t1.uniq_id = 4
+ORDER BY t2.c_amount;
+usr_id uniq_id increment usr2_id c_amount max
+3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,
+t2.usr2_id,t2.c_amount,t2.max
+FROM t2
+RIGHT JOIN t1 ON t2.id = t1.uniq_id
+WHERE t1.uniq_id = 4
+ORDER BY t2.c_amount;
+usr_id uniq_id increment usr2_id c_amount max
+3 4 84676 NULL NULL NULL
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+ERROR 23000: Duplicate entry '2-3' for key 'PRIMARY'
+INSERT INTO t2 VALUES (7,3,1000,2000,0,0,746294,937484,'yes');
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 ORDER BY t2.c_amount;
+usr_id uniq_id increment usr2_id c_amount max
+3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 GROUP BY t2.c_amount;
+usr_id uniq_id increment usr2_id c_amount max
+3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4;
+usr_id uniq_id increment usr2_id c_amount max
+3 4 84676 NULL NULL NULL
+drop table t1,t2;
+CREATE TABLE t1 (
+cod_asig int(11) DEFAULT '0' NOT NULL,
+desc_larga_cat varchar(80) DEFAULT '' NOT NULL,
+desc_larga_cas varchar(80) DEFAULT '' NOT NULL,
+desc_corta_cat varchar(40) DEFAULT '' NOT NULL,
+desc_corta_cas varchar(40) DEFAULT '' NOT NULL,
+cred_total double(3,1) DEFAULT '0.0' NOT NULL,
+pre_requisit int(11),
+co_requisit int(11),
+preco_requisit int(11),
+PRIMARY KEY (cod_asig)
+);
+INSERT INTO t1 VALUES (10360,'asdfggfg','Introduccion a los Ordenadores I','asdfggfg','Introduccio Ordinadors I',6.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10361,'Components i Circuits Electronics I','Componentes y Circuitos Electronicos I','Components i Circuits Electronics I','Comp. i Circ. Electr. I',6.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10362,'Laboratori d`Ordinadors','Laboratorio de Ordenadores','Laboratori d`Ordinadors','Laboratori Ordinadors',4.5,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10363,'Tecniques de Comunicacio Oral i Escrita','Tecnicas de Comunicacion Oral y Escrita','Tecniques de Comunicacio Oral i Escrita','Tec. Com. Oral i Escrita',4.5,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11403,'Projecte Fi de Carrera','Proyecto Fin de Carrera','Projecte Fi de Carrera','PFC',9.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11404,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',15.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11405,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',18.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11406,'Calcul Infinitesimal','Cßlculo Infinitesimal','Calcul Infinitesimal','Calcul Infinitesimal',15.0,NULL,NULL,NULL);
+CREATE TABLE t2 (
+idAssignatura int(11) DEFAULT '0' NOT NULL,
+Grup int(11) DEFAULT '0' NOT NULL,
+Places smallint(6) DEFAULT '0' NOT NULL,
+PlacesOcupades int(11) DEFAULT '0',
+PRIMARY KEY (idAssignatura,Grup)
+);
+INSERT INTO t2 VALUES (10360,12,333,0);
+INSERT INTO t2 VALUES (10361,30,2,0);
+INSERT INTO t2 VALUES (10361,40,3,0);
+INSERT INTO t2 VALUES (10360,45,10,0);
+INSERT INTO t2 VALUES (10362,10,12,0);
+INSERT INTO t2 VALUES (10360,55,2,0);
+INSERT INTO t2 VALUES (10360,70,0,0);
+INSERT INTO t2 VALUES (10360,565656,0,0);
+INSERT INTO t2 VALUES (10360,32767,7,0);
+INSERT INTO t2 VALUES (10360,33,8,0);
+INSERT INTO t2 VALUES (10360,7887,85,0);
+INSERT INTO t2 VALUES (11405,88,8,0);
+INSERT INTO t2 VALUES (10360,0,55,0);
+INSERT INTO t2 VALUES (10360,99,0,0);
+INSERT INTO t2 VALUES (11411,30,10,0);
+INSERT INTO t2 VALUES (11404,0,0,0);
+INSERT INTO t2 VALUES (10362,11,111,0);
+INSERT INTO t2 VALUES (10363,33,333,0);
+INSERT INTO t2 VALUES (11412,55,0,0);
+INSERT INTO t2 VALUES (50003,66,6,0);
+INSERT INTO t2 VALUES (11403,5,0,0);
+INSERT INTO t2 VALUES (11406,11,11,0);
+INSERT INTO t2 VALUES (11410,11410,131,0);
+INSERT INTO t2 VALUES (11416,11416,32767,0);
+INSERT INTO t2 VALUES (11409,0,0,0);
+CREATE TABLE t3 (
+id int(11) NOT NULL auto_increment,
+dni_pasaporte char(16) DEFAULT '' NOT NULL,
+idPla int(11) DEFAULT '0' NOT NULL,
+cod_asig int(11) DEFAULT '0' NOT NULL,
+any smallint(6) DEFAULT '0' NOT NULL,
+quatrimestre smallint(6) DEFAULT '0' NOT NULL,
+estat char(1) DEFAULT 'M' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE dni_pasaporte (dni_pasaporte,idPla),
+UNIQUE dni_pasaporte_2 (dni_pasaporte,idPla,cod_asig,any,quatrimestre)
+);
+INSERT INTO t3 VALUES (1,'11111111',1,10362,98,1,'M');
+CREATE TABLE t4 (
+id int(11) NOT NULL auto_increment,
+papa int(11) DEFAULT '0' NOT NULL,
+fill int(11) DEFAULT '0' NOT NULL,
+idPla int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY papa (idPla,papa),
+UNIQUE papa_2 (idPla,papa,fill)
+);
+INSERT INTO t4 VALUES (1,-1,10360,1);
+INSERT INTO t4 VALUES (2,-1,10361,1);
+INSERT INTO t4 VALUES (3,-1,10362,1);
+SELECT DISTINCT fill,desc_larga_cat,cred_total,Grup,Places,PlacesOcupades FROM t4 LEFT JOIN t3 ON t3.cod_asig=fill AND estat='S' AND dni_pasaporte='11111111' AND t3.idPla=1 , t2,t1 WHERE fill=t1.cod_asig AND Places>PlacesOcupades AND fill=idAssignatura AND t4.idPla=1 AND papa=-1;
+fill desc_larga_cat cred_total Grup Places PlacesOcupades
+10360 asdfggfg 6.0 12 333 0
+10361 Components i Circuits Electronics I 6.0 30 2 0
+10361 Components i Circuits Electronics I 6.0 40 3 0
+10360 asdfggfg 6.0 45 10 0
+10362 Laboratori d`Ordinadors 4.5 10 12 0
+10360 asdfggfg 6.0 55 2 0
+10360 asdfggfg 6.0 32767 7 0
+10360 asdfggfg 6.0 33 8 0
+10360 asdfggfg 6.0 7887 85 0
+10360 asdfggfg 6.0 0 55 0
+10362 Laboratori d`Ordinadors 4.5 11 111 0
+SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ;
+fill idPla
+10360 NULL
+10361 NULL
+10362 NULL
+INSERT INTO t3 VALUES (3,'1234',1,10360,98,1,'S');
+SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ;
+fill idPla
+10360 1
+10361 NULL
+10362 NULL
+drop table t1,t2,t3,test.t4;
+CREATE TABLE t1 (
+id smallint(5) unsigned NOT NULL auto_increment,
+name char(60) DEFAULT '' NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (1,'Antonio Paz');
+INSERT INTO t1 VALUES (2,'Lilliana Angelovska');
+INSERT INTO t1 VALUES (3,'Thimble Smith');
+CREATE TABLE t2 (
+id smallint(5) unsigned NOT NULL auto_increment,
+owner smallint(5) unsigned DEFAULT '0' NOT NULL,
+name char(60),
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES (1,1,'El Gato');
+INSERT INTO t2 VALUES (2,1,'Perrito');
+INSERT INTO t2 VALUES (3,3,'Happy');
+select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner);
+name name id
+Antonio Paz El Gato 1
+Antonio Paz Perrito 2
+Thimble Smith Happy 3
+Lilliana Angelovska NULL NULL
+select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
+name name id
+Lilliana Angelovska NULL NULL
+explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (flat, BNL join)
+explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.name is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+select count(*) from t1 left join t2 on (t1.id = t2.owner);
+count(*)
+4
+select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner);
+name name id
+Antonio Paz El Gato 1
+Antonio Paz Perrito 2
+Thimble Smith Happy 3
+Lilliana Angelovska NULL NULL
+select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
+name name id
+Lilliana Angelovska NULL NULL
+explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (flat, BNL join)
+explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.name is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+select count(*) from t2 right join t1 on (t1.id = t2.owner);
+count(*)
+4
+select t1.name, t2.name, t2.id,t3.id from t2 right join t1 on (t1.id = t2.owner) left join t1 as t3 on t3.id=t2.owner;
+name name id id
+Antonio Paz El Gato 1 1
+Antonio Paz Perrito 2 1
+Thimble Smith Happy 3 3
+Lilliana Angelovska NULL NULL NULL
+select t1.name, t2.name, t2.id,t3.id from t1 right join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner;
+name name id id
+Antonio Paz El Gato 1 1
+Antonio Paz Perrito 2 1
+Thimble Smith Happy 3 3
+NULL NULL NULL 2
+select t1.name, t2.name, t2.id, t2.owner, t3.id from t1 left join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner;
+name name id owner id
+Antonio Paz El Gato 1 1 1
+Antonio Paz Perrito 2 1 1
+Thimble Smith Happy 3 3 3
+NULL NULL NULL NULL 2
+drop table t1,t2;
+create table t1 (id int not null, str char(10), index(str));
+insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar");
+select * from t1 where str is not null order by id;
+id str
+3 foo
+4 bar
+select * from t1 where str is null;
+id str
+1 NULL
+2 NULL
+drop table t1;
+CREATE TABLE t1 (
+t1_id bigint(21) NOT NULL auto_increment,
+PRIMARY KEY (t1_id)
+);
+CREATE TABLE t2 (
+t2_id bigint(21) NOT NULL auto_increment,
+PRIMARY KEY (t2_id)
+);
+CREATE TABLE t3 (
+t3_id bigint(21) NOT NULL auto_increment,
+PRIMARY KEY (t3_id)
+);
+CREATE TABLE t4 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+KEY seq_0_id (seq_0_id),
+KEY seq_1_id (seq_1_id)
+);
+CREATE TABLE t5 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+KEY seq_1_id (seq_1_id),
+KEY seq_0_id (seq_0_id)
+);
+insert into t1 values (1);
+insert into t2 values (1);
+insert into t3 values (1);
+insert into t4 values (1,1);
+insert into t5 values (1,1);
+explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
+ERROR 42S22: Unknown column 't2.t2_id' in 'on clause'
+drop table t1,t2,t3,t4,t5;
+create table t1 (n int, m int, o int, key(n));
+create table t2 (n int not null, m int, o int, primary key(n));
+insert into t1 values (1, 2, 11), (1, 2, 7), (2, 2, 8), (1,2,9),(1,3,9);
+insert into t2 values (1, 2, 3),(2, 2, 8), (4,3,9),(3,2,10);
+select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
+t1.m = t2.m where t1.n = 1;
+n m o n m o
+1 2 11 1 2 3
+1 2 7 1 2 3
+1 2 9 1 2 3
+1 3 9 NULL NULL NULL
+select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
+t1.m = t2.m where t1.n = 1 order by t1.o;
+n m o n m o
+1 2 11 1 2 3
+1 2 7 1 2 3
+1 2 9 1 2 3
+1 3 9 NULL NULL NULL
+drop table t1,t2;
+CREATE TABLE t1 (id1 INT NOT NULL PRIMARY KEY, dat1 CHAR(1), id2 INT);
+INSERT INTO t1 VALUES (1,'a',1);
+INSERT INTO t1 VALUES (2,'b',1);
+INSERT INTO t1 VALUES (3,'c',2);
+CREATE TABLE t2 (id2 INT NOT NULL PRIMARY KEY, dat2 CHAR(1));
+INSERT INTO t2 VALUES (1,'x');
+INSERT INTO t2 VALUES (2,'y');
+INSERT INTO t2 VALUES (3,'z');
+SELECT t2.id2 FROM t2 LEFT OUTER JOIN t1 ON t1.id2 = t2.id2 WHERE id1 IS NULL;
+id2
+3
+SELECT t2.id2 FROM t2 NATURAL LEFT OUTER JOIN t1 WHERE id1 IS NULL;
+id2
+3
+drop table t1,t2;
+create table t1 ( color varchar(20), name varchar(20) );
+insert into t1 values ( 'red', 'apple' );
+insert into t1 values ( 'yellow', 'banana' );
+insert into t1 values ( 'green', 'lime' );
+insert into t1 values ( 'black', 'grape' );
+insert into t1 values ( 'blue', 'blueberry' );
+create table t2 ( count int, color varchar(20) );
+insert into t2 values (10, 'green');
+insert into t2 values (5, 'black');
+insert into t2 values (15, 'white');
+insert into t2 values (7, 'green');
+select * from t1;
+color name
+red apple
+yellow banana
+green lime
+black grape
+blue blueberry
+select * from t2;
+count color
+10 green
+5 black
+15 white
+7 green
+select * from t2 natural join t1;
+color count name
+green 10 lime
+green 7 lime
+black 5 grape
+select t2.count, t1.name from t2 natural join t1;
+count name
+10 lime
+7 lime
+5 grape
+select t2.count, t1.name from t2 inner join t1 using (color);
+count name
+10 lime
+7 lime
+5 grape
+drop table t1;
+drop table t2;
+CREATE TABLE t1 (
+pcode varchar(8) DEFAULT '' NOT NULL
+);
+INSERT INTO t1 VALUES ('kvw2000'),('kvw2001'),('kvw3000'),('kvw3001'),('kvw3002'),('kvw3500'),('kvw3501'),('kvw3502'),('kvw3800'),('kvw3801'),('kvw3802'),('kvw3900'),('kvw3901'),('kvw3902'),('kvw4000'),('kvw4001'),('kvw4002'),('kvw4200'),('kvw4500'),('kvw5000'),('kvw5001'),('kvw5500'),('kvw5510'),('kvw5600'),('kvw5601'),('kvw6000'),('klw1000'),('klw1020'),('klw1500'),('klw2000'),('klw2001'),('klw2002'),('kld2000'),('klw2500'),('kmw1000'),('kmw1500'),('kmw2000'),('kmw2001'),('kmw2100'),('kmw3000'),('kmw3200');
+CREATE TABLE t2 (
+pcode varchar(8) DEFAULT '' NOT NULL,
+KEY pcode (pcode)
+);
+INSERT INTO t2 VALUES ('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw6000'),('kvw6000'),('kld2000');
+SELECT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1
+LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode;
+pcode count
+kld2000 1
+klw1000 0
+klw1020 0
+klw1500 0
+klw2000 0
+klw2001 0
+klw2002 0
+klw2500 0
+kmw1000 0
+kmw1500 0
+kmw2000 0
+kmw2001 0
+kmw2100 0
+kmw3000 0
+kmw3200 0
+kvw2000 26
+kvw2001 0
+kvw3000 36
+kvw3001 0
+kvw3002 0
+kvw3500 26
+kvw3501 0
+kvw3502 0
+kvw3800 0
+kvw3801 0
+kvw3802 0
+kvw3900 0
+kvw3901 0
+kvw3902 0
+kvw4000 0
+kvw4001 0
+kvw4002 0
+kvw4200 0
+kvw4500 0
+kvw5000 0
+kvw5001 0
+kvw5500 0
+kvw5510 0
+kvw5600 0
+kvw5601 0
+kvw6000 2
+SELECT SQL_BIG_RESULT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1 LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode;
+pcode count
+kld2000 1
+klw1000 0
+klw1020 0
+klw1500 0
+klw2000 0
+klw2001 0
+klw2002 0
+klw2500 0
+kmw1000 0
+kmw1500 0
+kmw2000 0
+kmw2001 0
+kmw2100 0
+kmw3000 0
+kmw3200 0
+kvw2000 26
+kvw2001 0
+kvw3000 36
+kvw3001 0
+kvw3002 0
+kvw3500 26
+kvw3501 0
+kvw3502 0
+kvw3800 0
+kvw3801 0
+kvw3802 0
+kvw3900 0
+kvw3901 0
+kvw3902 0
+kvw4000 0
+kvw4001 0
+kvw4002 0
+kvw4200 0
+kvw4500 0
+kvw5000 0
+kvw5001 0
+kvw5500 0
+kvw5510 0
+kvw5600 0
+kvw5601 0
+kvw6000 2
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11),
+pid int(11),
+rep_del tinyint(4),
+KEY id (id),
+KEY pid (pid)
+);
+INSERT INTO t1 VALUES (1,NULL,NULL);
+INSERT INTO t1 VALUES (2,1,NULL);
+select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL;
+id pid rep_del id pid rep_del
+1 NULL NULL 2 1 NULL
+2 1 NULL NULL NULL NULL
+create index rep_del ON t1(rep_del);
+select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL;
+id pid rep_del id pid rep_del
+1 NULL NULL 2 1 NULL
+2 1 NULL NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+id int(11) DEFAULT '0' NOT NULL,
+name tinytext DEFAULT '' NOT NULL,
+UNIQUE id (id)
+);
+Warnings:
+Warning 1101 BLOB/TEXT column 'name' can't have a default value
+INSERT INTO t1 VALUES (1,'yes'),(2,'no');
+CREATE TABLE t2 (
+id int(11) DEFAULT '0' NOT NULL,
+idx int(11) DEFAULT '0' NOT NULL,
+UNIQUE id (id,idx)
+);
+INSERT INTO t2 VALUES (1,1);
+explain SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ref id id 4 test.t1.id 1 Using where; Using index; Not exists
+SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL;
+id name id idx
+2 no NULL NULL
+drop table t1,t2;
+create table t1 (bug_id mediumint, reporter mediumint);
+create table t2 (bug_id mediumint, who mediumint, index(who));
+insert into t2 values (1,1),(1,2);
+insert into t1 values (1,1),(2,1);
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.bug_id = t2.bug_id AND t2.who = 2) WHERE (t1.reporter = 2 OR t2.who = 2);
+bug_id reporter bug_id who
+1 1 1 2
+drop table t1,t2;
+create table t1 (fooID smallint unsigned auto_increment, primary key (fooID));
+create table t2 (fooID smallint unsigned not null, barID smallint unsigned not null, primary key (fooID,barID));
+insert into t1 (fooID) values (10),(20),(30);
+insert into t2 values (10,1),(20,2),(30,3);
+explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index
+1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using where; Using index
+select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
+fooID barID fooID
+10 1 NULL
+20 2 NULL
+30 3 30
+select * from t2 left join t1 ignore index(primary) on t1.fooID = t2.fooID and t1.fooID = 30;
+fooID barID fooID
+30 3 30
+10 1 NULL
+20 2 NULL
+drop table t1,t2;
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values(2),(4);
+select * from t1 natural left join t2 natural left join t3;
+i
+2
+1
+select * from t1 natural left join t2 where (t2.i is not null)=0;
+i
+1
+select * from t1 natural left join t2 where (t2.i is not null) is not null;
+i
+2
+1
+select * from t1 natural left join t2 where (i is not null)=0;
+i
+select * from t1 natural left join t2 where (i is not null) is not null;
+i
+2
+1
+drop table t1,t2,t3;
+create table t1 (f1 integer,f2 integer,f3 integer);
+create table t2 (f2 integer,f4 integer);
+create table t3 (f3 integer,f5 integer);
+select * from t1
+left outer join t2 using (f2)
+left outer join t3 using (f3);
+f3 f2 f1 f4 f5
+drop table t1,t2,t3;
+create table t1 (a1 int, a2 int);
+create table t2 (b1 int not null, b2 int);
+create table t3 (c1 int, c2 int);
+insert into t1 values (1,2), (2,2), (3,2);
+insert into t2 values (1,3), (2,3);
+insert into t3 values (2,4), (3,4);
+select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
+a1 a2 b1 b2 c1 c2
+1 2 1 3 NULL NULL
+2 2 2 3 NULL NULL
+3 2 NULL NULL 3 4
+explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+drop table t1, t2, t3;
+create table t1 (
+a int(11),
+b char(10),
+key (a)
+);
+insert into t1 (a) values (1),(2),(3),(4);
+create table t2 (a int);
+select * from t1 left join t2 on t1.a=t2.a where not (t2.a <=> t1.a);
+a b a
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+select * from t1 left join t2 on t1.a=t2.a having not (t2.a <=> t1.a);
+a b a
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+drop table t1,t2;
+create table t1 (
+match_id tinyint(3) unsigned not null auto_increment,
+home tinyint(3) unsigned default '0',
+unique key match_id (match_id),
+key match_id_2 (match_id)
+);
+insert into t1 values("1", "2");
+create table t2 (
+player_id tinyint(3) unsigned default '0',
+match_1_h tinyint(3) unsigned default '0',
+key player_id (player_id)
+);
+insert into t2 values("1", "5");
+insert into t2 values("2", "9");
+insert into t2 values("3", "3");
+insert into t2 values("4", "7");
+insert into t2 values("5", "6");
+insert into t2 values("6", "8");
+insert into t2 values("7", "4");
+insert into t2 values("8", "12");
+insert into t2 values("9", "11");
+insert into t2 values("10", "10");
+explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
+(t2 s left join t1 m on m.match_id = 1)
+order by m.match_id desc;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
+1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer (flat, BKA join)
+explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
+(t2 s left join t1 m on m.match_id = 1)
+order by UUX desc;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
+1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer (flat, BKA join)
+select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
+(t2 s left join t1 m on m.match_id = 1)
+order by UUX desc;
+player_id match_1_h * match_id home UUX
+8 12 * 1 2 10
+9 11 * 1 2 9
+10 10 * 1 2 8
+2 9 * 1 2 7
+6 8 * 1 2 6
+4 7 * 1 2 5
+5 6 * 1 2 4
+1 5 * 1 2 3
+7 4 * 1 2 2
+3 3 * 1 2 1
+explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
+t2 s straight_join t1 m where m.match_id = 1
+order by UUX desc;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
+1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer (flat, BKA join)
+select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
+t2 s straight_join t1 m where m.match_id = 1
+order by UUX desc;
+player_id match_1_h * match_id home UUX
+8 12 * 1 2 10
+9 11 * 1 2 9
+10 10 * 1 2 8
+2 9 * 1 2 7
+6 8 * 1 2 6
+4 7 * 1 2 5
+5 6 * 1 2 4
+1 5 * 1 2 3
+7 4 * 1 2 2
+3 3 * 1 2 1
+drop table t1, t2;
+create table t1 (a int, b int, unique index idx (a, b));
+create table t2 (a int, b int, c int, unique index idx (a, b));
+insert into t1 values (1, 10), (1,11), (2,10), (2,11);
+insert into t2 values (1,10,3);
+select t1.a, t1.b, t2.c from t1 left join t2
+on t1.a=t2.a and t1.b=t2.b and t2.c=3
+where t1.a=1 and t2.c is null;
+a b c
+1 11 NULL
+drop table t1, t2;
+CREATE TABLE t1 (
+ts_id bigint(20) default NULL,
+inst_id tinyint(4) default NULL,
+flag_name varchar(64) default NULL,
+flag_value text,
+UNIQUE KEY ts_id (ts_id,inst_id,flag_name)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ts_id bigint(20) default NULL,
+inst_id tinyint(4) default NULL,
+flag_name varchar(64) default NULL,
+flag_value text,
+UNIQUE KEY ts_id (ts_id,inst_id,flag_name)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES
+(111056548820001, 0, 'flag1', NULL),
+(111056548820001, 0, 'flag2', NULL),
+(2, 0, 'other_flag', NULL);
+INSERT INTO t2 VALUES
+(111056548820001, 3, 'flag1', 'sss');
+SELECT t1.flag_name,t2.flag_value
+FROM t1 LEFT JOIN t2
+ON (t1.ts_id = t2.ts_id AND t1.flag_name = t2.flag_name AND
+t2.inst_id = 3)
+WHERE t1.inst_id = 0 AND t1.ts_id=111056548820001 AND
+t2.flag_value IS NULL;
+flag_name flag_value
+flag2 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL auto_increment,
+text_id int(10) unsigned default NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES("1", "0");
+INSERT INTO t1 VALUES("2", "10");
+CREATE TABLE t2 (
+text_id char(3) NOT NULL default '',
+language_id char(3) NOT NULL default '',
+text_data text,
+PRIMARY KEY (text_id,language_id)
+);
+INSERT INTO t2 VALUES("0", "EN", "0-EN");
+INSERT INTO t2 VALUES("0", "SV", "0-SV");
+INSERT INTO t2 VALUES("10", "EN", "10-EN");
+INSERT INTO t2 VALUES("10", "SV", "10-SV");
+SELECT t1.id, t1.text_id, t2.text_data
+FROM t1 LEFT JOIN t2
+ON t1.text_id = t2.text_id
+AND t2.language_id = 'SV'
+ WHERE (t1.id LIKE '%' OR t2.text_data LIKE '%');
+id text_id text_data
+1 0 0-SV
+2 10 10-SV
+DROP TABLE t1, t2;
+CREATE TABLE t0 (a0 int PRIMARY KEY);
+CREATE TABLE t1 (a1 int PRIMARY KEY);
+CREATE TABLE t2 (a2 int);
+CREATE TABLE t3 (a3 int);
+INSERT INTO t0 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+SELECT * FROM t1 LEFT JOIN t2 ON a1=0;
+a1 a2
+1 NULL
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON a1=0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
+a1 a2 a3
+1 NULL NULL
+EXPLAIN SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2
+SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
+a0 a1 a2 a3
+1 1 NULL NULL
+EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t0 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2
+INSERT INTO t0 VALUES (0);
+INSERT INTO t1 VALUES (0);
+SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
+a0 a1 a2 a3
+1 1 NULL NULL
+EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t0 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2
+drop table t1,t2;
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 (a int, b int);
+insert into t2 values (1,1), (2,2);
+select * from t2 right join t1 on t2.a=t1.a;
+a b a b
+1 1 1 1
+2 2 2 2
+NULL NULL 3 3
+select straight_join * from t2 right join t1 on t2.a=t1.a;
+a b a b
+1 1 1 1
+2 2 2 2
+NULL NULL 3 3
+DROP TABLE t0,t1,t2,t3;
+CREATE TABLE t1 (a int PRIMARY KEY, b int);
+CREATE TABLE t2 (a int PRIMARY KEY, b int);
+INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (4,2);
+INSERT INTO t2 VALUES (1,2), (2,2);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a;
+a b a b
+1 1 1 2
+2 1 2 2
+3 1 NULL NULL
+4 2 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t1.b=1;
+a b a b
+1 1 1 2
+2 1 2 2
+3 1 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
+WHERE t1.b=1 XOR (NOT ISNULL(t2.a) AND t2.b=1);
+a b a b
+1 1 1 2
+2 1 2 2
+3 1 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE not(0+(t1.a=30 and t2.b=1));
+a b a b
+1 1 1 2
+2 1 2 2
+3 1 NULL NULL
+4 2 NULL NULL
+DROP TABLE t1,t2;
+set group_concat_max_len=5;
+create table t1 (a int, b varchar(20));
+create table t2 (a int, c varchar(20));
+insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb");
+insert into t2 values (1,"cccccccccc"),(2,"dddddddddd");
+select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by t1.a;
+group_concat(t1.b,t2.c)
+aaaaa
+bbbbb
+Warnings:
+Warning 1260 2 line(s) were cut by GROUP_CONCAT()
+select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a;
+group_concat(t1.b,t2.c)
+aaaaa
+bbbbb
+Warnings:
+Warning 1260 2 line(s) were cut by GROUP_CONCAT()
+select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a;
+group_concat(t1.b,t2.c)
+aaaaa
+bbbbb
+Warnings:
+Warning 1260 2 line(s) were cut by GROUP_CONCAT()
+select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a;
+group_concat(t1.b,t2.c)
+aaaaa
+bbbbb
+Warnings:
+Warning 1260 2 line(s) were cut by GROUP_CONCAT()
+drop table t1, t2;
+set group_concat_max_len=default;
+create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y));
+insert t1 values (1, -5, -8, 2), (1, 2, 2, 1), (1, 1, 1, 1);
+create table t2 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, id int(11) not null, primary key (gid,id,x,y), key id (id));
+insert t2 values (1, -5, -8, 1), (1, 1, 1, 1), (1, 2, 2, 1);
+create table t3 ( set_id smallint(5) unsigned not null, id tinyint(4) unsigned not null, name char(12) not null, primary key (id,set_id));
+insert t3 values (0, 1, 'a'), (1, 1, 'b'), (0, 2, 'c'), (1, 2, 'd'), (1, 3, 'e'), (1, 4, 'f'), (1, 5, 'g'), (1, 6, 'h');
+explain select name from t1 left join t2 on t1.x = t2.x and t1.y = t2.y
+left join t3 on t1.art = t3.id where t2.id =1 and t2.x = -5 and t2.y =-8
+and t1.gid =1 and t2.gid =1 and t3.set_id =1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 10 const,const,const 1
+1 SIMPLE t2 const PRIMARY,id PRIMARY 14 const,const,const,const 1 Using index
+1 SIMPLE t3 const PRIMARY PRIMARY 3 const,const 1
+drop tables t1,t2,t3;
+CREATE TABLE t1 (EMPNUM INT, GRP INT);
+INSERT INTO t1 VALUES (0, 10);
+INSERT INTO t1 VALUES (2, 30);
+CREATE TABLE t2 (EMPNUM INT, NAME CHAR(5));
+INSERT INTO t2 VALUES (0, 'KERI');
+INSERT INTO t2 VALUES (9, 'BARRY');
+CREATE VIEW v1 AS
+SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS EMPNUM, NAME, GRP
+FROM t2 LEFT OUTER JOIN t1 ON t2.EMPNUM=t1.EMPNUM;
+SELECT * FROM v1;
+EMPNUM NAME GRP
+0 KERI 10
+9 BARRY NULL
+SELECT * FROM v1 WHERE EMPNUM < 10;
+EMPNUM NAME GRP
+0 KERI 10
+9 BARRY NULL
+DROP VIEW v1;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (c11 int);
+CREATE TABLE t2 (c21 int);
+INSERT INTO t1 VALUES (30), (40), (50);
+INSERT INTO t2 VALUES (300), (400), (500);
+SELECT * FROM t1 LEFT JOIN t2 ON (c11=c21 AND c21=30) WHERE c11=40;
+c11 c21
+40 NULL
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int PRIMARY KEY, b int);
+CREATE TABLE t2 (a int PRIMARY KEY, b int);
+INSERT INTO t1 VALUES (1,2), (2,1), (3,2), (4,3), (5,6), (6,5), (7,8), (8,7), (9,10);
+INSERT INTO t2 VALUES (3,0), (4,1), (6,4), (7,5);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.b <= t1.a AND t1.a <= t1.b;
+a b a b
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a BETWEEN t2.b AND t1.b;
+a b a b
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a NOT BETWEEN t2.b AND t1.b);
+a b a b
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.b > t1.a OR t1.a > t1.b;
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+2 1 NULL NULL
+8 7 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a NOT BETWEEN t2.b AND t1.b;
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+2 1 NULL NULL
+8 7 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a BETWEEN t2.b AND t1.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+2 1 NULL NULL
+8 7 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t2.b > t1.a OR t1.a > t1.b;
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+2 1 NULL NULL
+8 7 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a != t2.a AND t1.a BETWEEN t2.b AND t1.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+2 1 NULL NULL
+8 7 NULL NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a AND (t2.b > t1.a OR t1.a > t1.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a != t2.a OR t1.a BETWEEN t2.b AND t1.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b;
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a NOT IN(t2.a, t2.b));
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a != t1.b AND t1.a != t2.b;
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a NOT IN(t1.b, t2.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a IN(t1.b, t2.b));
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.a != t2.b OR (t1.a != t2.a AND t1.a != t2.b);
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t2.a = t2.b AND t1.a IN(t2.a, t2.b));
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.a != t2.b AND t1.a != t1.b AND t1.a != t2.b;
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t2.a = t2.b OR t1.a IN(t1.b, t2.b));
+a b a b
+3 2 3 0
+4 3 4 1
+6 5 6 4
+7 8 7 5
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer (flat, BKA join)
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer (flat, BKA join)
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b-2, t2.b, t2.b-1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer (flat, BKA join)
+DROP TABLE t1,t2;
+DROP VIEW IF EXISTS v1,v2;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a int);
+CREATE table t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
+INSERT INTO t2 VALUES (2), (3);
+CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
+CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
+SELECT v1.a, v2. b
+FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
+GROUP BY v1.a;
+a b
+2 NULL
+3 3
+SELECT v1.a, v2. b
+FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
+GROUP BY v1.a;
+a b
+2 NULL
+3 3
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (2), (3);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1);
+a b
+2 2
+3 3
+1 NULL
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1);
+a b
+2 2
+3 3
+1 NULL
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1);
+a b
+2 2
+3 3
+1 NULL
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2);
+a b
+2 2
+3 3
+1 NULL
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0);
+a b
+2 2
+3 3
+1 NULL
+4 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+f1 varchar(16) collate latin1_swedish_ci PRIMARY KEY,
+f2 varchar(16) collate latin1_swedish_ci
+);
+CREATE TABLE t2 (
+f1 varchar(16) collate latin1_swedish_ci PRIMARY KEY,
+f3 varchar(16) collate latin1_swedish_ci
+);
+INSERT INTO t1 VALUES ('bla','blah');
+INSERT INTO t2 VALUES ('bla','sheep');
+SELECT * FROM t1 JOIN t2 USING(f1) WHERE f1='Bla';
+f1 f2 f3
+bla blah sheep
+SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='bla';
+f1 f2 f3
+bla blah sheep
+SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='Bla';
+f1 f2 f3
+bla blah sheep
+DROP TABLE t1,t2;
+CREATE TABLE t1 (id int PRIMARY KEY, a varchar(8));
+CREATE TABLE t2 (id int NOT NULL, b int NOT NULL, INDEX idx(id));
+INSERT INTO t1 VALUES
+(1,'aaaaaaa'), (5,'eeeeeee'), (4,'ddddddd'), (2,'bbbbbbb'), (3,'ccccccc');
+INSERT INTO t2 VALUES
+(3,10), (2,20), (5,30), (3,20), (5,10), (3,40), (3,30), (2,10), (2,40);
+EXPLAIN
+SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref idx idx 4 test.t1.id 2 Using where; Not exists; Using join buffer (flat, BKA join)
+flush status;
+SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
+id a
+1 aaaaaaa
+4 ddddddd
+show status like 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 5
+Handler_read_next 9
+Handler_read_prev 0
+Handler_read_rnd 3
+Handler_read_rnd_next 6
+DROP TABLE t1,t2;
+CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL);
+INSERT INTO t1 VALUES (1,0), (2,1);
+CREATE TABLE t2 (d int PRIMARY KEY);
+INSERT INTO t2 VALUES (1), (2), (3);
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Not exists
+SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL;
+c e d
+1 0 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d<=>NULL;
+c e d
+1 0 NULL
+DROP TABLE t1,t2;
+#
+# Bug#47650: using group by with rollup without indexes returns incorrect
+# results with where
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( a INT, b INT );
+INSERT INTO t2 VALUES (1, 1),(1, 2),(1, 3),(2, 4),(2, 5);
+EXPLAIN
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 LEFT JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 LEFT JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b )
+1 3 6 3
+NULL 3 6 3
+EXPLAIN
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b )
+1 3 6 3
+NULL 3 6 3
+DROP TABLE t1, t2;
+#
+# Bug#51598 Inconsistent behaviour with a COALESCE statement inside an IN comparison
+#
+CREATE TABLE t1(f1 INT, f2 INT, f3 INT);
+INSERT INTO t1 VALUES (1, NULL, 3);
+CREATE TABLE t2(f1 INT, f2 INT);
+INSERT INTO t2 VALUES (2, 1);
+EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN t2 ON t1.f2 = t2.f2
+WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '1' AS `f1`,NULL AS `f2`,'3' AS `f3`,NULL AS `f1`,NULL AS `f2` from `test`.`t1` left join `test`.`t2` on(multiple equal(NULL)) where ((coalesce('1',NULL),'3') in ((1,3),(2,2)))
+SELECT * FROM t1 LEFT JOIN t2 ON t1.f2 = t2.f2
+WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2));
+f1 f2 f3 f1 f2
+1 NULL 3 NULL NULL
+DROP TABLE t1, t2;
+#
+# Bug#52357: Assertion failed: join->best_read in greedy_search
+# optimizer_search_depth=0
+#
+CREATE TABLE t1( a INT );
+INSERT INTO t1 VALUES (1),(2);
+SET optimizer_search_depth = 0;
+# Should not core dump on query preparation
+EXPLAIN
+SELECT 1
+FROM t1 tt3 LEFT OUTER JOIN t1 tt4 ON 1
+LEFT OUTER JOIN t1 tt5 ON 1
+LEFT OUTER JOIN t1 tt6 ON 1
+LEFT OUTER JOIN t1 tt7 ON 1
+LEFT OUTER JOIN t1 tt8 ON 1
+RIGHT OUTER JOIN t1 tt2 ON 1
+RIGHT OUTER JOIN t1 tt1 ON 1
+STRAIGHT_JOIN t1 tt9 ON 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE tt1 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE tt3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE tt4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE tt5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE tt6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE tt7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE tt8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE tt9 ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+SET optimizer_search_depth = DEFAULT;
+DROP TABLE t1;
+#
+# Bug#46091 STRAIGHT_JOIN + RIGHT JOIN returns different result
+#
+CREATE TABLE t1 (f1 INT NOT NULL);
+INSERT INTO t1 VALUES (9),(0);
+CREATE TABLE t2 (f1 INT NOT NULL);
+INSERT INTO t2 VALUES
+(5),(3),(0),(3),(1),(0),(1),(7),(1),(0),(0),(8),(4),(9),(0),(2),(0),(8),(5),(1);
+SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1
+RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1;
+COUNT(*)
+476
+EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1
+RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE TA2 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE TA3 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 SIMPLE TA1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+DROP TABLE t1, t2;
+#
+# Bug#48971 Segfault in add_found_match_trig_cond () at sql_select.cc:5990
+#
+CREATE TABLE t1(f1 INT, PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
+LEFT JOIN t1 AS jt2
+RIGHT JOIN t1 AS jt3
+JOIN t1 AS jt4 ON 1
+LEFT JOIN t1 AS jt5 ON 1
+ON 1
+RIGHT JOIN t1 AS jt6 ON jt6.f1
+ON 1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using index
+1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1))) on(1) where 1
+EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
+RIGHT JOIN t1 AS jt2
+RIGHT JOIN t1 AS jt3
+JOIN t1 AS jt4 ON 1
+LEFT JOIN t1 AS jt5 ON 1
+ON 1
+RIGHT JOIN t1 AS jt6 ON jt6.f1
+ON 1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using index
+1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
+DROP TABLE t1;
+#
+# Bug#49600: outer join of two single-row tables with joining attributes
+# evaluated to nulls
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1, NULL);
+insert into t2 values (2, NULL);
+select * from t1 left join t2 on t1.b=t2.b;
+a b a b
+1 NULL NULL NULL
+select * from t1 left join t2 on t1.b=t2.b where 1=1;
+a b a b
+1 NULL NULL NULL
+drop table t1,t2;
+#
+# Bug#53161: outer join in the derived table is erroneously converted
+# into an inner join for a query with a group by clause
+#
+create table t1 (pk int not null primary key, a int not null);
+create table t2 like t1;
+create table t3 like t1;
+create table t4 (pk int not null primary key);
+insert into t1 values (1000, 1), (1001, 1);
+insert into t2 values (2000, 2), (2001, 2);
+insert into t3 values (3000, 3), (3001, 2);
+insert into t4 values (4000), (4001);
+explain extended
+select t2.pk,
+(select t3.pk+if(isnull(t4.pk),0,t4.pk)
+from t3 left join t4 on t4.pk=t3.pk
+where t3.pk=t2.pk+1000 limit 1 ) as t
+from t1,t2
+where t2.pk=t1.pk+1000 and t1.pk>1000
+group by t2.pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using temporary; Using filesort
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index
+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`,<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
+where t3.pk=t2.pk+1000 limit 1 ) as t
+from t1,t2
+where t2.pk=t1.pk+1000 and t1.pk>1000
+group by t2.pk;
+pk t
+2001 3001
+drop table t1,t2,t3,t4;
+#
+# Bug#57024: Poor performance when conjunctive condition over the outer
+# table is used in the on condition of an outer join
+#
+create table t1 (a int);
+insert into t1 values (NULL), (NULL), (NULL), (NULL);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 values (4), (2), (1), (3);
+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);
+analyze table t1,t2,t3;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+test.t3 analyze status OK
+flush status;
+select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null;
+sum(t3.b)
+1006
+show status like "handler_read%";
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 4
+Handler_read_next 5
+Handler_read_prev 0
+Handler_read_rnd 5
+Handler_read_rnd_next 1048581
+flush status;
+select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10;
+sum(t3.b)
+1006
+show status like "handler_read%";
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 4
+Handler_read_next 5
+Handler_read_prev 0
+Handler_read_rnd 5
+Handler_read_rnd_next 1048581
+drop table t1,t2,t3;
+#
+# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
+#
+CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1));
+CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2));
+INSERT INTO t1 VALUES (4);
+INSERT INTO t2 VALUES (3, 3);
+INSERT INTO t2 VALUES (7, 7);
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
+WHERE t1.f1 = 4
+GROUP BY t2.f1, t2.f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using temporary; Using filesort
+1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using index
+SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
+WHERE t1.f1 = 4
+GROUP BY t2.f1, t2.f2;
+f1 f1 f2
+4 NULL NULL
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
+WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
+GROUP BY t2.f1, t2.f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using filesort
+1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index
+SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
+WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
+GROUP BY t2.f1, t2.f2;
+f1 f1 f2
+DROP TABLE t1,t2;
+End of 5.1 tests
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index 314b7656322..87d0a5bd9b5 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -136,7 +136,7 @@ i
explain select count(*) from t1, t2 where t1.p = t2.i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index
-1 SIMPLE t2 ref k1 k1 5 test.t1.p 2 Using where; Using index
+1 SIMPLE t2 ref k1 k1 5 test.t1.p 2 Using index
select count(*) from t1, t2 where t1.p = t2.i;
count(*)
3
@@ -629,7 +629,7 @@ select p from t1 where p between 1010 and 1020;
p
explain select i from t2 where p between 1010 and 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using where
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using index condition; Using MRR
select i from t2 where p between 1010 and 1020;
i
1
@@ -645,7 +645,7 @@ i
3
explain select count(*) from t1, t2 where t1.p = t2.i;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index k1 k1 5 NULL 1024 Using index
+1 SIMPLE t2 index k1 k1 5 NULL 1024 Using where; Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.i 1 Using index
select count(*) from t1, t2 where t1.p = t2.i;
count(*)
diff --git a/mysql-test/r/key_diff.result b/mysql-test/r/key_diff.result
index 9d26bee4557..af928fcb203 100644
--- a/mysql-test/r/key_diff.result
+++ b/mysql-test/r/key_diff.result
@@ -36,7 +36,7 @@ a a a a
explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL a NULL NULL NULL 5
-1 SIMPLE t2 ALL b NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t2 ALL b NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
a b a b
A B a a
diff --git a/mysql-test/r/lowercase_mixed_tmpdir_innodb.result b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result
index a478b49cfda..a478b49cfda 100755..100644
--- a/mysql-test/r/lowercase_mixed_tmpdir_innodb.result
+++ b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result
diff --git a/mysql-test/r/maria_mrr.result b/mysql-test/r/maria_mrr.result
new file mode 100644
index 00000000000..bf1173e0bed
--- /dev/null
+++ b/mysql-test/r/maria_mrr.result
@@ -0,0 +1,405 @@
+drop table if exists t1,t2,t3,t4;
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set @save_storage_engine= @@storage_engine;
+set storage_engine=aria;
+create table t1(a int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
+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 + 10*C.a) from t1 A, t1 B, t1 C;
+create table t3 (
+a char(8) not null, b char(8) not null, filler char(200),
+key(a)
+);
+insert into t3 select @a:=concat('c-', 1000+ A.a, '=w'), @a, 'filler' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 2000+A.a, '=w'),
+'filler-1' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 3000+A.a, '=w'),
+'filler-2' from t2 A;
+select a,filler from t3 where a >= 'c-9011=w';
+a filler
+select a,filler from t3 where a >= 'c-1011=w' and a <= 'c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+(a>='c-1014=w' and a <= 'c-1015=w');
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+insert into t3 values ('c-1013=z', 'c-1013=z', 'err');
+insert into t3 values ('a-1014=w', 'a-1014=w', 'err');
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+(a>='c-1014=w' and a <= 'c-1015=w');
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+delete from t3 where b in ('c-1013=z', 'a-1014=w');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+a='c-1014=w' or a='c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+insert into t3 values ('c-1013=w', 'del-me', 'inserted');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+a='c-1014=w' or a='c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+c-1013=w inserted
+delete from t3 where b='del-me';
+alter table t3 add primary key(b);
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+b IN ('c-1019=w', 'c-1020=w', 'c-1021=w',
+'c-1022=w', 'c-1023=w', 'c-1024=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+c-1024=w filler
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1020=w') or
+b IN ('c-1021=w', 'c-1022=w', 'c-1023=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+b IN ('c-1019=w', 'c-1020=w') or
+(b>='c-1021=w' and b<= 'c-1023=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+drop table if exists t4;
+create table t4 (a varchar(10), b int, c char(10), filler char(200),
+key idx1 (a, b, c));
+insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'b-1',NULL,'c-1', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'b-1',NULL,'c-222', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'bb-1',NULL,'cc-2', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'zz-1',NULL,'cc-2', 'filler-data' from t2 order by a limit 500;
+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; Using MRR
+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
+NULL NULL NULL NULL-15
+NULL NULL NULL NULL-14
+NULL NULL NULL NULL-13
+NULL NULL NULL NULL-12
+NULL NULL NULL NULL-11
+NULL NULL NULL NULL-10
+NULL NULL NULL NULL-9
+NULL NULL NULL NULL-8
+NULL NULL NULL NULL-7
+NULL NULL NULL NULL-6
+NULL NULL NULL NULL-5
+NULL NULL NULL NULL-4
+NULL NULL NULL NULL-3
+NULL NULL NULL NULL-2
+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; Using MRR
+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
+b-1 NULL c-1 NULL-14
+b-1 NULL c-1 NULL-13
+b-1 NULL c-1 NULL-12
+b-1 NULL c-1 NULL-11
+b-1 NULL c-1 NULL-10
+b-1 NULL c-1 NULL-9
+b-1 NULL c-1 NULL-8
+b-1 NULL c-1 NULL-7
+b-1 NULL c-1 NULL-6
+b-1 NULL c-1 NULL-5
+b-1 NULL c-1 NULL-4
+b-1 NULL c-1 NULL-3
+b-1 NULL c-1 NULL-2
+b-1 NULL c-1 NULL-1
+bb-1 NULL cc-2 NULL-15
+bb-1 NULL cc-2 NULL-14
+bb-1 NULL cc-2 NULL-13
+bb-1 NULL cc-2 NULL-12
+bb-1 NULL cc-2 NULL-11
+bb-1 NULL cc-2 NULL-10
+bb-1 NULL cc-2 NULL-9
+bb-1 NULL cc-2 NULL-8
+bb-1 NULL cc-2 NULL-7
+bb-1 NULL cc-2 NULL-6
+bb-1 NULL cc-2 NULL-5
+bb-1 NULL cc-2 NULL-4
+bb-1 NULL cc-2 NULL-3
+bb-1 NULL cc-2 NULL-2
+bb-1 NULL cc-2 NULL-1
+select * from t4 ignore index(idx1) 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
+b-1 NULL c-1 NULL-14
+b-1 NULL c-1 NULL-13
+b-1 NULL c-1 NULL-12
+b-1 NULL c-1 NULL-11
+b-1 NULL c-1 NULL-10
+b-1 NULL c-1 NULL-9
+b-1 NULL c-1 NULL-8
+b-1 NULL c-1 NULL-7
+b-1 NULL c-1 NULL-6
+b-1 NULL c-1 NULL-5
+b-1 NULL c-1 NULL-4
+b-1 NULL c-1 NULL-3
+b-1 NULL c-1 NULL-2
+b-1 NULL c-1 NULL-1
+bb-1 NULL cc-2 NULL-15
+bb-1 NULL cc-2 NULL-14
+bb-1 NULL cc-2 NULL-13
+bb-1 NULL cc-2 NULL-12
+bb-1 NULL cc-2 NULL-11
+bb-1 NULL cc-2 NULL-10
+bb-1 NULL cc-2 NULL-9
+bb-1 NULL cc-2 NULL-8
+bb-1 NULL cc-2 NULL-7
+bb-1 NULL cc-2 NULL-6
+bb-1 NULL cc-2 NULL-5
+bb-1 NULL cc-2 NULL-4
+bb-1 NULL cc-2 NULL-3
+bb-1 NULL cc-2 NULL-2
+bb-1 NULL cc-2 NULL-1
+drop table t1, t2, t3, t4;
+create table t1 (a int, b int not null,unique key (a,b),index(b));
+insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6);
+create table t2 like t1;
+insert into t2 select * from t1;
+alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
+select * from t1 where a is null;
+a b c
+NULL 7 0
+NULL 9 0
+NULL 9 0
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
+a b c
+NULL 9 0
+NULL 9 0
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
+a b c
+NULL 7 0
+NULL 9 0
+NULL 9 0
+drop table t1, t2;
+set storage_engine= @save_storage_engine;
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+#
+# Crash in quick_range_seq_next() in maria-5.3-dsmrr-cpk with join_cache_level = {8,1}
+#
+set @save_join_cache_level= @@join_cache_level;
+SET SESSION join_cache_level = 8;
+CREATE TABLE `t1` (
+`col_int_key` int(11) DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO `t1` VALUES (6,'2005-10-07 00:00:00','e','e');
+INSERT INTO `t1` VALUES (51,'2000-07-15 05:00:34','f','f');
+CREATE TABLE `t2` (
+`col_int_key` int(11) DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO `t2` VALUES (2,'2004-10-11 18:13:16','w','w');
+INSERT INTO `t2` VALUES (2,'1900-01-01 00:00:00','d','d');
+SELECT table2 .`col_datetime_key`
+FROM t2 JOIN ( t1 table2 JOIN t2 table3 ON table3 .`col_varchar_key` < table2 .`col_varchar_key` ) ON table3 .`col_varchar_nokey` ;
+col_datetime_key
+drop table t1, t2;
+set join_cache_level=@save_join_cache_level;
+CREATE TABLE t1(
+pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+PRIMARY KEY (pk), INDEX idx (v, i)
+) ENGINE=ARIA;
+INSERT INTO t1 VALUES
+(1,9,'x'), (2,5,'g'), (3,1,'o'), (4,0,'g'), (5,1,'v'),
+(6,190,'m'), (7,6,'x'), (8,3,'c'), (9,4,'z'), (10,3,'i'),
+(11,186,'x'), (12,1,'g'), (13,8,'q'), (14,226,'m'), (15,133,'p');
+CREATE TABLE t2(
+pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+PRIMARY KEY (pk), INDEX idx (v, i)
+) ENGINE=ARIA;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t2 VALUES (77, 333, 'z');
+CREATE TABLE t3(
+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') ;
+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)
+120
+EXPLAIN
+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;
+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)
+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)
+120
+EXPLAIN
+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;
+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,idx NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ref PRIMARY,idx idx 3 test.t2.v 2 Using index condition; Using where
+DROP TABLE t1,t2,t3;
+#
+# BUG#671361: virtual int Mrr_ordered_index_reader::refill_buffer(): Assertion `!know_key_tuple_params
+# (works only on Maria because we need 1024-byte long key)
+#
+SET SESSION optimizer_use_mrr = 'force';
+SET SESSION join_cache_level = 6;
+SET SESSION join_buffer_size = 1024;
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL,
+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');
+CREATE TABLE t2 (
+col_varchar_10_latin1 varchar(10) DEFAULT NULL
+) ENGINE=Aria;
+INSERT INTO t2 VALUES ('foo'), ('foo');
+EXPLAIN SELECT count(*)
+FROM t1 AS table1, t2 AS table2
+WHERE
+table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE table2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE table1 ref PRIMARY,col_varchar_1024_latin1_key col_varchar_1024_latin1_key 1027 test.table2.col_varchar_10_latin1 2 Using index condition(BKA); Using where; Using join buffer (flat, BKA join)
+SELECT count(*)
+FROM t1 AS table1, t2 AS table2
+WHERE
+table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ;
+count(*)
+0
+drop table t1, t2;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 717437a0532..ada82c54675 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -673,7 +673,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE fileset_id = 2
AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,files PRIMARY 35 NULL 5 Using where
+1 SIMPLE t1 range PRIMARY,files PRIMARY 35 NULL 5 Using index condition; Using MRR
EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
AND file_code = '0000000115' LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/mix2_myisam.result b/mysql-test/r/mix2_myisam.result
index e0a3d1af089..676fd06fc8b 100644
--- a/mysql-test/r/mix2_myisam.result
+++ b/mysql-test/r/mix2_myisam.result
@@ -1114,11 +1114,11 @@ count(*)
29267
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using where
+1 SIMPLE t1 range c c 5 NULL # Using index condition; Using MRR
update t1 set c=a;
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using where
+1 SIMPLE t1 range c c 5 NULL # Using index condition; Using MRR
drop table t1,t2;
create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) engine=MyISAM;
insert into t1 (id) values (null),(null),(null),(null),(null);
@@ -1559,7 +1559,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -1735,7 +1735,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using where
+1 SIMPLE t1 ref v v 303 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index ccfb223dfcc..1174ba7dfcf 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -346,32 +346,32 @@ t1 1 c_2 2 a A 5 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 ALL a NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
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 ALL a NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
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
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
-1 SIMPLE t1 ref b b 5 test.t2.b 1 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 2 Using where
+1 SIMPLE t1 ref b b 5 test.t2.b 1
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 ALL a NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
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 ALL a NULL NULL NULL 5 Using where
explain select * from t1 force index (a) where a=0 or a=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 4 NULL 4 Using where
+1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Using MRR
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 Using where
+1 SIMPLE t1 ref c,c_2 c 5 const 1
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
@@ -1230,7 +1230,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -1406,7 +1406,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using where
+1 SIMPLE t1 ref v v 303 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result
new file mode 100644
index 00000000000..e1eeb4e1a62
--- /dev/null
+++ b/mysql-test/r/myisam_mrr.result
@@ -0,0 +1,510 @@
+drop table if exists t0, t1, t2, t3;
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=79;
+Warnings:
+Warning 1292 Truncated incorrect mrr_buffer_size value: '79'
+create table t1(a int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+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 + 10*C.a) from t1 A, t1 B, t1 C;
+create table t3 (
+a char(8) not null, b char(8) not null, filler char(200),
+key(a)
+);
+insert into t3 select @a:=concat('c-', 1000+ A.a, '=w'), @a, 'filler' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 2000+A.a, '=w'),
+'filler-1' from t2 A;
+insert into t3 select concat('c-', 1000+A.a, '=w'), concat('c-', 3000+A.a, '=w'),
+'filler-2' from t2 A;
+select a,filler from t3 where a >= 'c-9011=w';
+a filler
+select a,filler from t3 where a >= 'c-1011=w' and a <= 'c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+(a>='c-1014=w' and a <= 'c-1015=w');
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+insert into t3 values ('c-1013=z', 'c-1013=z', 'err');
+insert into t3 values ('a-1014=w', 'a-1014=w', 'err');
+select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
+(a>='c-1014=w' and a <= 'c-1015=w');
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+delete from t3 where b in ('c-1013=z', 'a-1014=w');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+a='c-1014=w' or a='c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+insert into t3 values ('c-1013=w', 'del-me', 'inserted');
+select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
+a='c-1014=w' or a='c-1015=w';
+a filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1011=w filler-1
+c-1012=w filler-1
+c-1013=w filler-1
+c-1014=w filler-1
+c-1015=w filler-1
+c-1011=w filler-2
+c-1012=w filler-2
+c-1013=w filler-2
+c-1014=w filler-2
+c-1015=w filler-2
+c-1013=w inserted
+delete from t3 where b='del-me';
+alter table t3 add primary key(b);
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+b IN ('c-1019=w', 'c-1020=w', 'c-1021=w',
+'c-1022=w', 'c-1023=w', 'c-1024=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+c-1024=w filler
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1020=w') or
+b IN ('c-1021=w', 'c-1022=w', 'c-1023=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
+b IN ('c-1019=w', 'c-1020=w') or
+(b>='c-1021=w' and b<= 'c-1023=w');
+b filler
+c-1011=w filler
+c-1012=w filler
+c-1013=w filler
+c-1014=w filler
+c-1015=w filler
+c-1016=w filler
+c-1017=w filler
+c-1018=w filler
+c-1019=w filler
+c-1020=w filler
+c-1021=w filler
+c-1022=w filler
+c-1023=w filler
+drop table if exists t4;
+create table t4 (a varchar(10), b int, c char(10), filler char(200),
+key idx1 (a, b, c));
+insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'b-1',NULL,'c-1', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'b-1',NULL,'c-222', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'bb-1',NULL,'cc-2', concat('NULL-', 15-a) from t2 order by a limit 15;
+insert into t4 (a,b,c,filler)
+select 'zz-1',NULL,'cc-2', 'filler-data' from t2 order by a limit 500;
+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; Using MRR
+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
+NULL NULL NULL NULL-15
+NULL NULL NULL NULL-14
+NULL NULL NULL NULL-13
+NULL NULL NULL NULL-12
+NULL NULL NULL NULL-11
+NULL NULL NULL NULL-10
+NULL NULL NULL NULL-9
+NULL NULL NULL NULL-8
+NULL NULL NULL NULL-7
+NULL NULL NULL NULL-6
+NULL NULL NULL NULL-5
+NULL NULL NULL NULL-4
+NULL NULL NULL NULL-3
+NULL NULL NULL NULL-2
+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; Using MRR
+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
+b-1 NULL c-1 NULL-14
+b-1 NULL c-1 NULL-13
+b-1 NULL c-1 NULL-12
+b-1 NULL c-1 NULL-11
+b-1 NULL c-1 NULL-10
+b-1 NULL c-1 NULL-9
+b-1 NULL c-1 NULL-8
+b-1 NULL c-1 NULL-7
+b-1 NULL c-1 NULL-6
+b-1 NULL c-1 NULL-5
+b-1 NULL c-1 NULL-4
+b-1 NULL c-1 NULL-3
+b-1 NULL c-1 NULL-2
+b-1 NULL c-1 NULL-1
+bb-1 NULL cc-2 NULL-15
+bb-1 NULL cc-2 NULL-14
+bb-1 NULL cc-2 NULL-13
+bb-1 NULL cc-2 NULL-12
+bb-1 NULL cc-2 NULL-11
+bb-1 NULL cc-2 NULL-10
+bb-1 NULL cc-2 NULL-9
+bb-1 NULL cc-2 NULL-8
+bb-1 NULL cc-2 NULL-7
+bb-1 NULL cc-2 NULL-6
+bb-1 NULL cc-2 NULL-5
+bb-1 NULL cc-2 NULL-4
+bb-1 NULL cc-2 NULL-3
+bb-1 NULL cc-2 NULL-2
+bb-1 NULL cc-2 NULL-1
+select * from t4 ignore index(idx1) 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
+b-1 NULL c-1 NULL-14
+b-1 NULL c-1 NULL-13
+b-1 NULL c-1 NULL-12
+b-1 NULL c-1 NULL-11
+b-1 NULL c-1 NULL-10
+b-1 NULL c-1 NULL-9
+b-1 NULL c-1 NULL-8
+b-1 NULL c-1 NULL-7
+b-1 NULL c-1 NULL-6
+b-1 NULL c-1 NULL-5
+b-1 NULL c-1 NULL-4
+b-1 NULL c-1 NULL-3
+b-1 NULL c-1 NULL-2
+b-1 NULL c-1 NULL-1
+bb-1 NULL cc-2 NULL-15
+bb-1 NULL cc-2 NULL-14
+bb-1 NULL cc-2 NULL-13
+bb-1 NULL cc-2 NULL-12
+bb-1 NULL cc-2 NULL-11
+bb-1 NULL cc-2 NULL-10
+bb-1 NULL cc-2 NULL-9
+bb-1 NULL cc-2 NULL-8
+bb-1 NULL cc-2 NULL-7
+bb-1 NULL cc-2 NULL-6
+bb-1 NULL cc-2 NULL-5
+bb-1 NULL cc-2 NULL-4
+bb-1 NULL cc-2 NULL-3
+bb-1 NULL cc-2 NULL-2
+bb-1 NULL cc-2 NULL-1
+drop table t1, t2, t3, t4;
+create table t1 (a int, b int not null,unique key (a,b),index(b));
+insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6);
+create table t2 like t1;
+insert into t2 select * from t1;
+alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
+select * from t1 where a is null;
+a b c
+NULL 7 0
+NULL 9 0
+NULL 9 0
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
+a b c
+NULL 9 0
+NULL 9 0
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
+a b c
+NULL 7 0
+NULL 9 0
+NULL 9 0
+drop table t1, t2;
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+col1 int(10) unsigned DEFAULT NULL,
+key1 int(10) unsigned NOT NULL DEFAULT '0',
+key2 int(10) unsigned DEFAULT NULL,
+text1 text,
+text2 text,
+col2 smallint(6) DEFAULT '100',
+col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (ID),
+KEY (key1),
+KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES
+(1,NULL,1130,NULL,'Hello',NULL,100,'bodyandsubject',0),
+(2,NULL,1130,NULL,'bye',NULL,100,'bodyandsubject',0),
+(3,NULL,1130,NULL,'red',NULL,100,'bodyandsubject',0),
+(4,NULL,1130,NULL,'yellow',NULL,100,'bodyandsubject',0),
+(5,NULL,1130,NULL,'blue',NULL,100,'bodyandsubject',0);
+select * FROM t1 WHERE key1=1130 AND col1 IS NULL ORDER BY text1;
+ID col1 key1 key2 text1 text2 col2 col3 col4
+5 NULL 1130 NULL blue NULL 100 bodyandsubject 0
+2 NULL 1130 NULL bye NULL 100 bodyandsubject 0
+1 NULL 1130 NULL Hello NULL 100 bodyandsubject 0
+3 NULL 1130 NULL red NULL 100 bodyandsubject 0
+4 NULL 1130 NULL yellow NULL 100 bodyandsubject 0
+drop table t1;
+
+BUG#37851: Crash in test_if_skip_sort_order tab->select is zero
+
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+int_key int(11) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY int_key (int_key)
+);
+INSERT INTO t2 VALUES (1,1),(2,6),(3,0);
+EXPLAIN EXTENDED
+SELECT MIN(t1.pk)
+FROM t1 WHERE EXISTS (
+SELECT t2.pk
+FROM t2
+WHERE t2.int_key IS NULL
+GROUP BY t2.pk
+);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY t2 ref int_key int_key 5 1 100.00 Using index condition; Using where; Using filesort
+Warnings:
+Note 1003 select min(`test`.`t1`.`pk`) AS `MIN(t1.pk)` from `test`.`t1` where 0
+DROP TABLE t1, t2;
+#
+# BUG#42048 Discrepancy between MyISAM and Maria's ICP implementation
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b char(20), filler char(200), key(a,b(10)));
+insert into t1 select A.a + 10*(B.a + 10*C.a), 'bbb','filler' from t0 A, t0 B, t0 C;
+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
+select * from t1 where a < 10 and b = repeat(char(65+a), 20);
+a b filler
+0 AAAAAAAAAAAAAAAAAAAA filler
+1 BBBBBBBBBBBBBBBBBBBB filler
+2 CCCCCCCCCCCCCCCCCCCC filler
+3 DDDDDDDDDDDDDDDDDDDD filler
+4 EEEEEEEEEEEEEEEEEEEE filler
+5 FFFFFFFFFFFFFFFFFFFF filler
+6 GGGGGGGGGGGGGGGGGGGG filler
+7 HHHHHHHHHHHHHHHHHHHH filler
+8 IIIIIIIIIIIIIIIIIIII filler
+9 JJJJJJJJJJJJJJJJJJJJ filler
+drop table t0,t1;
+#
+# BUG#41136: ORDER BY + range access: EXPLAIN shows "Using MRR" while MRR is actually not used
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, key(a));
+insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 A, t0 B, t0 C;
+This mustn't show "Using MRR":
+explain select * from t1 where a < 20 order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 20 Using index condition
+drop table t0, t1;
+#
+# Part of MWL#67: DS-MRR backport: add an @@optimizer_switch flag for
+# index_condition pushdown:
+# - engine_condition_pushdown does not affect ICP
+select @@optimizer_switch like '%index_condition_pushdown=on%';
+@@optimizer_switch like '%index_condition_pushdown=on%'
+1
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, key(a));
+insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 A, t0 B, t0 C;
+A query that will use ICP:
+explain select * from t1 where a < 20;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 20 Using index condition; Using MRR
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='index_condition_pushdown=off';
+explain select * from t1 where a < 20;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 20 Using where; Using MRR
+set optimizer_switch='index_condition_pushdown=on';
+explain select * from t1 where a < 20;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 20 Using index condition; Using MRR
+set optimizer_switch=@save_optimizer_switch;
+#
+# BUG#629684: Unreachable code in multi_range_read.cc in maria-5.3-dsmrr-cpk
+#
+delete from t0 where a > 2;
+insert into t0 values (NULL),(NULL);
+insert into t1 values (NULL, 1234), (NULL, 5678);
+set @save_join_cache_level=@@join_cache_level;
+set @@join_cache_level=6;
+explain
+select * from t0, t1 where t0.a<=>t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t0 ALL NULL NULL NULL NULL 5
+1 SIMPLE t1 ref a a 5 test.t0.a 1 Using index condition(BKA); Using join buffer (flat, BKA join)
+select * from t0, t1 where t0.a<=>t1.a;
+a a b
+0 0 0
+1 1 1
+2 2 2
+NULL NULL 1234
+NULL NULL 1234
+NULL NULL 5678
+NULL NULL 5678
+set @@join_cache_level=@save_join_cache_level;
+drop table t0, t1;
+#
+# BUG#625841: Assertion `!table || (!table->read_set || bitmap_is_set
+# (table->read_set, field_index))' on REPLACE ... SELECT with MRR
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+key1 varchar(10),
+col1 char(255), col2 char(255),
+col3 char(244), col4 char(255),
+key(key1)
+);
+create table t2 like t1;
+insert into t1
+select
+1000+A.a+100*B.a + 10*C.a,
+'col1val', 'col2val',
+'col3val', 'col4val'
+from t0 A, t0 B, t0 C;
+REPLACE INTO t2(col2,col3,col4)
+SELECT col2,col3,col4
+FROM t1
+WHERE `key1` LIKE CONCAT( LEFT( '1' , 7 ) , '%' )
+ORDER BY col1 LIMIT 7;
+drop table t0, t1, t2;
+#
+# BUG#670417: Diverging results in maria-5.3-mwl128-dsmrr-cpk with join buffer (incremental, BKA join)
+#
+set @save_join_cache_level = @@join_cache_level;
+set join_cache_level = 6;
+set @save_join_buffer_size=@@join_buffer_size;
+set join_buffer_size = 136;
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) NOT NULL,
+col_varchar_key varchar(1) NOT NULL,
+col_varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t1 VALUES
+(10,8,'v','v'),(11,8,'f','f'), (12,5,'v','v'),
+(13,8,'s','s'),(14,8,'a','a'),(15,6,'p','p'),
+(16,7,'z','z'),(17,2,'a','a'),(18,5,'h','h'),
+(19,7,'h','h'),(20,2,'v','v'),(21,9,'v','v'),
+(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');
+SELECT COUNT(*)
+FROM
+t1 AS table2, t1 AS table3
+where
+table3.col_varchar_key = table2.col_varchar_key AND
+table3.col_varchar_key = table2.col_varchar_nokey AND
+table3.pk<>0;
+COUNT(*)
+50
+EXPLAIN SELECT COUNT(*)
+FROM
+t1 AS table2, t1 AS table3
+where
+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 index condition(BKA); Using where; Using join buffer (flat, BKA join)
+set join_cache_level= @save_join_cache_level;
+set join_buffer_size= @save_join_buffer_size;
+drop table t1;
diff --git a/mysql-test/r/named_pipe.result b/mysql-test/r/named_pipe.result
index 32e96fa27b7..57b38a97549 100644
--- a/mysql-test/r/named_pipe.result
+++ b/mysql-test/r/named_pipe.result
@@ -183,37 +183,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1389,15 +1389,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1413,15 +1413,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
diff --git a/mysql-test/r/negation_elimination.result b/mysql-test/r/negation_elimination.result
index 91a4c273832..dea0d865d87 100644
--- a/mysql-test/r/negation_elimination.result
+++ b/mysql-test/r/negation_elimination.result
@@ -79,7 +79,7 @@ a
19
explain select * from t1 where not(a != 10);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
+1 SIMPLE t1 ref a a 5 const 1 Using index
select * from t1 where not(a != 1);
a
1
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 1cdc48e6552..897366787f1 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -148,10 +148,10 @@ insert into t1 values
(7,7), (8,8), (9,9), (10,10), (11,11), (12,12);
explain select * from t1 where a between 2 and 3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx idx 4 NULL 2 Using where
+1 SIMPLE t1 range idx idx 4 NULL 2 Using index condition; Using MRR
explain select * from t1 where a between 2 and 3 or b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx idx 4 NULL 2 Using where
+1 SIMPLE t1 range idx idx 4 NULL 2 Using index condition; Using MRR
drop table t1;
select cast(NULL as signed);
cast(NULL as signed)
@@ -170,7 +170,7 @@ insert into t1 select i*2 from t1;
insert into t1 values(null);
explain select * from t1 where i=2 or i is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null i i 5 const 9 Using where; Using index
+1 SIMPLE t1 ref_or_null i i 5 const 9 Using index
select count(*) from t1 where i=2 or i is null;
count(*)
10
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index 58c587fe588..67725c45314 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -21,10 +21,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a,b a 9 NULL 3 Using where; Using index
explain select * from t1 where (a is null or a = 7) and b=7;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using where; Using index
+1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using index
explain select * from t1 where (a is null or a = 7) and b=7 order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using where; Using index; Using filesort
+1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using index; Using filesort
explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 3 Using where; Using index
@@ -151,7 +151,7 @@ alter table t1 modify b int null;
insert into t1 values (7,null), (8,null), (8,7);
explain select * from t1 where a = 7 and (b=7 or b is null);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 10 const,const 2 Using where; Using index
+1 SIMPLE t1 ref_or_null a,b a 10 const,const 2 Using index
select * from t1 where a = 7 and (b=7 or b is null);
a b
7 7
@@ -166,7 +166,7 @@ a b
NULL 7
explain select * from t1 where (a = 7 or a is null) and (a = 7 or a is null);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a a 5 const 5 Using where; Using index
+1 SIMPLE t1 ref_or_null a a 5 const 5 Using index
select * from t1 where (a = 7 or a is null) and (a = 7 or a is null);
a b
7 NULL
@@ -178,12 +178,12 @@ create table t2 (a int);
insert into t2 values (7),(8);
explain select * from t2 straight_join t1 where t1.a=t2.a and b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t1 ref a,b a 10 test.t2.a,const 2 Using where; Using index
drop index b on t1;
explain select * from t2,t1 where t1.a=t2.a and b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t1 ref a a 10 test.t2.a,const 2 Using where; Using index
select * from t2,t1 where t1.a=t2.a and b is null;
a a b
@@ -191,8 +191,8 @@ a a b
8 8 NULL
explain select * from t2,t1 where t1.a=t2.a and (b= 7 or b is null);
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_or_null a a 10 test.t2.a,const 4 Using where; Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t1 ref_or_null a a 10 test.t2.a,const 4 Using index
select * from t2,t1 where t1.a=t2.a and (b= 7 or b is null);
a a b
7 7 7
@@ -202,7 +202,7 @@ a a b
explain select * from t2,t1 where (t1.a=t2.a or t1.a is null) and b= 7;
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_or_null a a 10 test.t2.a,const 4 Using where; Using index
+1 SIMPLE t1 ref_or_null a a 10 test.t2.a,const 4 Using index
select * from t2,t1 where (t1.a=t2.a or t1.a is null) and b= 7;
a a b
7 7 7
@@ -226,7 +226,7 @@ delete from t1 where a=8;
explain select * from t2,t1 where t1.a=t2.a or t1.a is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 4
-1 SIMPLE t1 ref_or_null a a 5 test.t2.a 4 Using where; Using index
+1 SIMPLE t1 ref_or_null a a 5 test.t2.a 4 Using index
explain select * from t2,t1 where t1.a<=>t2.a or (t1.a is null and t1.b <> 9);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 4
@@ -258,7 +258,7 @@ INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4
INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
explain select id from t1 where uniq_id is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref idx1 idx1 5 const 5 Using where
+1 SIMPLE t1 ref idx1 idx1 5 const 5 Using index condition
explain select id from t1 where uniq_id =1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const idx1 idx1 5 const 1
@@ -407,8 +407,8 @@ EXPLAIN SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 ref idx idx 5 test.t1.a 1
-1 SIMPLE t3 ref idx idx 5 test.t2.b 1 Using index
+1 SIMPLE t2 ref idx idx 5 test.t1.a 1 Using where
+1 SIMPLE t3 ref idx idx 5 test.t2.b 1 Using where; Using index
FLUSH STATUS ;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
diff --git a/mysql-test/r/optimizer_switch.result b/mysql-test/r/optimizer_switch.result
new file mode 100644
index 00000000000..6c9b7254a7c
--- /dev/null
+++ b/mysql-test/r/optimizer_switch.result
@@ -0,0 +1,99 @@
+#
+# Generic @@optimizer_switch tests
+#
+#
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='index_merge=off,index_merge_union=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='index_merge_union=on';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,index_merge_sort_union=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch=4;
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
+set optimizer_switch=NULL;
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'NULL'
+set optimizer_switch='default,index_merge';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
+set optimizer_switch='index_merge=index_merge';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=index_merge'
+set optimizer_switch='index_merge=on,but...';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'but...'
+set optimizer_switch='index_merge=';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge='
+set optimizer_switch='index_merge';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
+set optimizer_switch='on';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'on'
+set optimizer_switch='index_merge=on,index_merge=off';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off'
+set optimizer_switch='index_merge_union=on,index_merge_union=default';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge_union=default'
+set optimizer_switch='default,index_merge=on,index_merge=off,default';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off,default'
+set optimizer_switch=default;
+set optimizer_switch='index_merge=off,index_merge_union=off,default';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch=default;
+select @@global.optimizer_switch;
+@@global.optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set @@global.optimizer_switch=default;
+select @@global.optimizer_switch;
+@@global.optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+#
+# Check index_merge's @@optimizer_switch flags
+#
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+
+BUG#37120 optimizer_switch allowable values not according to specification
+
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,materialization=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,semijoin=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,semijoin=off,materialization=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,materialization=off,semijoin=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,semijoin=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch='default,materialization=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on
+set optimizer_switch=default;
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index ba639fa9763..ab4a5fa220e 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using index condition
drop table t1,t2,t3;
CREATE TABLE t1 (
`titre` char(80) NOT NULL default '',
@@ -607,9 +607,14 @@ FieldKey LongVal StringVal
1 0 2
1 1 3
1 2 1
-EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+DS-MRR: use two IGNORE INDEX queries, otherwise we get cost races, because
+DS-MRR: records_in_range/read_time return the same numbers for all three indexes
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range FieldKey,LongField,StringField FieldKey 38 NULL 4 Using where; Using filesort
+1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Using MRR; 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
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
FieldKey LongVal StringVal
3 1 2
@@ -638,7 +643,7 @@ 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);
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 3 Using filesort
select * from t1 where b=1 or b is null order by a;
a b
1 1
@@ -647,7 +652,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 4 Using filesort
select * from t1 where b=2 or b is null order by a;
a b
3 NULL
@@ -1004,7 +1009,7 @@ t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2)
ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
-1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
SELECT t2.b as c FROM
t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2)
ORDER BY c;
@@ -1107,7 +1112,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index k2 k3 5 NULL 73 Using where
EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range k2 k2 5 NULL 386 Using where; Using filesort
+1 SIMPLE t2 range k2 k2 5 NULL 386 Using index condition; Using where; Using MRR; Using filesort
SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20;
id c3
6 14
@@ -1484,8 +1489,8 @@ SELECT d FROM t1, t2
WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a,b b 4 const 4 Using where; Using temporary; Using filesort
-1 SIMPLE t2 ref a,b,c a 40 test.t1.a,const 11 Using where
+1 SIMPLE t1 ref a,b b 4 const 4 Using index condition; Using where; Using temporary; Using filesort
+1 SIMPLE t2 ref a,b,c a 40 test.t1.a,const 11 Using index condition
SELECT d FROM t1, t2
WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
@@ -1602,20 +1607,20 @@ INSERT INTO t2 SELECT a+4, b FROM t2;
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 10
+1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Using MRR; Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
# should have "using filesort"
EXPLAIN
SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
-1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
+1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Using MRR; Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
# should have "using filesort"
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
-1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
+1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Using MRR; Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
DROP TABLE t1, t2;
#
# Bug #50394: Regression in EXPLAIN with index scan, LIMIT, GROUP BY and
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 01ae3876fd0..75097b8d411 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -771,7 +771,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index
+1 SIMPLE t1 pNULL ref a a 4 const 1 Using index
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1100,7 +1100,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index
+1 SIMPLE t1 pNULL ref a a 4 const 1 Using index
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -2537,15 +2537,15 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 510 Using where
explain partitions select * from t2 where b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 Using where
+1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76
explain extended select * from t2 where b = 6;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ref b b 5 const 76 100.00 Using where
+1 SIMPLE t2 ref b b 5 const 76 100.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = 6)
explain partitions select * from t2 where b = 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 Using where
+1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76
explain extended select * from t2 where b in (1,3,5);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL b NULL NULL NULL 910 40.66 Using where
diff --git a/mysql-test/r/pool_of_threads.result b/mysql-test/r/pool_of_threads.result
index 42460a8040c..74ea7ba12eb 100644
--- a/mysql-test/r/pool_of_threads.result
+++ b/mysql-test/r/pool_of_threads.result
@@ -183,37 +183,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1389,15 +1389,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1413,15 +1413,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1429,7 +1429,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index b3f4ad017d3..e13790f8eaf 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -149,6 +149,8 @@ c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
c32 set('monday', 'tuesday', 'wednesday')
) engine = MYISAM ;
create table t2 like t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
prepare stmt1 from @stmt ;
execute stmt1 ;
@@ -177,6 +179,7 @@ id select_type table type possible_keys key key_len ref rows Extra
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
deallocate prepare stmt1;
drop tables t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
set @arg00=1;
prepare stmt1 from ' create table t1 (m int) as select 1 as m ' ;
execute stmt1 ;
@@ -3010,13 +3013,13 @@ PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1';
EXECUTE stmt;
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
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1
EXECUTE stmt;
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
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1
DEALLOCATE PREPARE stmt;
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index 8d578794d6d..174d7764cf3 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -465,9 +465,9 @@ def key 253 64 7 Y 0 31 8
def key_len 253 4096 1 Y 0 31 8
def ref 253 2048 0 Y 0 31 8
def rows 8 10 1 Y 32928 0 63
-def Extra 253 255 27 N 1 31 8
+def Extra 253 255 48 N 1 31 8
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using index condition; Using MRR; Using filesort
drop table if exists t2;
create table t2 (id smallint, name varchar(20)) ;
prepare stmt1 from ' insert into t2 values(?, ?) ' ;
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 528e66650cd..751a545d988 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1509,8 +1509,8 @@ prepare stmt1 from 'insert into t1 values(?,?),(?,?)';
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
select a,b from t1 where a in (@arg00,@arg02) ;
a b
-81 8-1
82 8-2
+81 8-1
set @arg00=9 ;
set @arg01='nine' ;
prepare stmt1 from 'insert into t1 set a=?, b=? ';
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index d989896514c..7653b824b0c 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -220,31 +220,31 @@ insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
update t1 set y=x;
explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Using MRR; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Using MRR; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
explain select count(*) from t1 where x in (1);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref x x 5 const 1 Using where; Using index
+1 SIMPLE t1 ref x x 5 const 1 Using index
explain select count(*) from t1 where x in (1,2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index
@@ -256,12 +256,12 @@ INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using index
-1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer
+1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
explain select * from t1 force index(i1), t2 force index(j1) where
(t1.key1 <t2.keya + 1) and t2.keya=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using index
-1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer
+1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
DROP TABLE t1,t2;
CREATE TABLE t1 (
a int(11) default NULL,
@@ -276,7 +276,7 @@ INSERT INTO t1 VALUES
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 2 Using where
+1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where; Using MRR
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
@@ -421,19 +421,19 @@ test.t1 analyze status OK
test.t2 analyze status Table is already up to date
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using where
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Using MRR
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using where
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Using MRR
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using where
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Using MRR
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using where
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Using MRR
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id name uid id name uid
@@ -615,13 +615,13 @@ INSERT INTO t1 (a) VALUES
('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
explain select * from t1 where a='aaa';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 11 const 2 Using where
+1 SIMPLE t1 ref a a 11 const 2 Using index condition
explain select * from t1 where a=binary 'aaa';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 11 NULL 2 Using where
+1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Using MRR
explain select * from t1 where a='aaa' collate latin1_bin;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 11 NULL 2 Using where
+1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Using MRR
explain select * from t1 where a='aaa' collate latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
@@ -704,7 +704,7 @@ WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using where
+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)
SELECT s.oxid FROM t1 v, t1 s
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
@@ -878,10 +878,10 @@ INSERT INTO t1 VALUES
(55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C');
EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 11 Using where
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Using MRR
EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 11 Using where
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Using MRR
SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
id status
53 C
@@ -910,10 +910,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 10 Using where
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Using MRR
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 where
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Using MRR
SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
id status
53 C
@@ -1014,20 +1014,20 @@ create table t2 (a varchar(10), filler char(200), key(a));
insert into t2 select * from t1;
explain select * from t1 where a between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using where
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Using MRR
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 where
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Using MRR
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 where
+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 where
+1 SIMPLE t2 ref a a 13 const # Using index condition
update t1 set a='b' where a<>'a';
explain select * from t1 where a not between 'b' and 'b';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using where
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Using MRR
select a, hex(filler) from t1 where a not between 'b' and 'b';
a hex(filler)
a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
@@ -1071,10 +1071,10 @@ id b c
0 3 4
EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using index condition; Using where; Using MRR
EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where; Using MRR
SELECT * FROM t1 WHERE 0 < b OR 0 > c;
id b c
0 3 4
@@ -1085,10 +1085,10 @@ id b c
0 3 4
EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
+1 SIMPLE t1 ALL idx1,idx2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
+1 SIMPLE t1 ALL idx1,idx2 NULL NULL NULL 10 Using where
DROP TABLE t1;
CREATE TABLE t1 (
item char(20) NOT NULL default '',
@@ -1103,7 +1103,7 @@ INSERT INTO t1 VALUES
('A2','2005-12-01 08:00:00',1000);
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
Warnings:
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
@@ -1151,7 +1151,7 @@ INSERT INTO t1 VALUES
This must use range access:
explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where
+1 SIMPLE t1 range dateval dateval 4 NULL 2 Using index condition; Using MRR
drop table t1;
CREATE TABLE t1 (
a varchar(32), index (a)
@@ -1217,7 +1217,7 @@ Z
In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)
explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 5 const 502 Using where
+1 SIMPLE t2 ref a a 5 const 502 Using index condition
drop table t1, t2;
CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index 789b9c4f383..80934a4e01f 100644
--- a/mysql-test/r/row.result
+++ b/mysql-test/r/row.result
@@ -377,7 +377,7 @@ a b a b c
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 8 NULL 6 100.00 Using index
-1 SIMPLE t2 index NULL PRIMARY 12 NULL 7 100.00 Using where; Using index; Using join buffer
+1 SIMPLE t2 index NULL PRIMARY 12 NULL 7 100.00 Using where; Using index; Using join buffer (flat, BNL 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`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t1`.`a` - 1) = (`test`.`t2`.`a` - 1)) and (`test`.`t1`.`b` = (`test`.`t2`.`b` + 1)))
SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index c1aa5704f56..6d3a3717c67 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -185,37 +185,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1391,15 +1391,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1415,15 +1415,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1431,7 +1431,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
@@ -2362,16 +2362,16 @@ insert into t1 values (1,2), (2,2), (3,2), (4,2);
insert into t2 values (1,3), (2,3), (3,4), (4,4);
explain select * from t1 left join t2 on a=c where d in (4);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref c,d d 5 const 2 Using where
-1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ref c,d d 5 const 2
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
select * from t1 left join t2 on a=c where d in (4);
a b c d
3 2 3 4
4 2 4 4
explain select * from t1 left join t2 on a=c where d = 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref c,d d 5 const 2 Using where
-1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ref c,d d 5 const 2
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
select * from t1 left join t2 on a=c where d = 4;
a b c d
3 2 3 4
@@ -2397,11 +2397,11 @@ 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
-1 SIMPLE t2 ref a a 23 test.t1.a 2
+1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE 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
-1 SIMPLE t2 ref a a 23 test.t1.a 2
+1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where
DROP TABLE t1, t2;
CREATE TABLE t1 ( city char(30) );
INSERT INTO t1 VALUES ('London');
@@ -2716,8 +2716,8 @@ explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
t2.b like '%%' order by t2.b limit 0,1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort
-1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
+1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
+1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a int, INDEX idx(a));
@@ -2738,7 +2738,7 @@ ALTER TABLE t1 ENABLE KEYS;
EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b b 5 NULL 2 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
a b a b
1 NULL 1 1
@@ -2748,7 +2748,7 @@ a b a b
EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b b 5 NULL 2 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
a b a b
1 NULL 1 1
@@ -2910,11 +2910,11 @@ a
EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 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
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON 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 3
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
DROP TABLE t1,t2;
select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
@@ -3417,7 +3417,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 where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -3453,7 +3453,7 @@ In next EXPLAIN, B.rows must be exactly 10:
explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using where
+1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using index condition; Using where; Using MRR
1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10
drop table t1, t2;
CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
@@ -3467,13 +3467,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
-1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using MRR
+1 SIMPLE t2 ref c c 5 test.t1.a 2
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
-1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Using MRR
+1 SIMPLE t2 ref c c 5 test.t1.a 2
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,
@@ -3533,7 +3533,7 @@ WHERE t1.id=2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
1 SIMPLE t2 const idx1 NULL NULL NULL 1
-1 SIMPLE t3 ref idx1 idx1 5 const 3 Using where
+1 SIMPLE t3 ref idx1 idx1 5 const 3
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
WHERE t1.id=2;
id a b c d e
@@ -3562,19 +3562,19 @@ EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk < 'c' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Using MRR
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
@@ -3608,7 +3608,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 4 Using where
+1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3616,7 +3616,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee') ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 4 Using where
+1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
@@ -3624,7 +3624,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 2 Using where
+1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3632,7 +3632,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
+1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
@@ -3752,7 +3752,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range ts ts 4 NULL 1 Using where
+1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where; Using MRR
Warnings:
Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
@@ -3854,7 +3854,7 @@ cc 3 7
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref name name 6 test.t1.name 2
+1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where
SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
name name n
ccc NULL NULL
@@ -3928,7 +3928,7 @@ cc 3 7
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref name name 6 test.t1.name 2
+1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where
SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
name name n
ccc NULL NULL
@@ -4376,12 +4376,12 @@ CREATE TABLE t1 (a INT KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Using MRR
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Using MRR
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
@@ -4396,7 +4396,7 @@ INSERT INTO t1 VALUES
EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL a NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2 Range checked for each record (index map: 0x1)
SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
1
1
@@ -4406,7 +4406,7 @@ SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL a NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2 Range checked for each record (index map: 0x1)
SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
1
1
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
new file mode 100644
index 00000000000..ba5d3cddacb
--- /dev/null
+++ b/mysql-test/r/select_jcl6.result
@@ -0,0 +1,4811 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+drop table if exists t1,t2,t3,t4,t11;
+drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa;
+drop view if exists v1;
+CREATE TABLE t1 (
+Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
+Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
+);
+INSERT INTO t1 VALUES (9410,9412);
+select period from t1;
+period
+9410
+select * from t1;
+Period Varor_period
+9410 9412
+select t1.* from t1;
+Period Varor_period
+9410 9412
+CREATE TABLE t2 (
+auto int not null auto_increment,
+fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
+companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
+fld3 char(30) DEFAULT '' NOT NULL,
+fld4 char(35) DEFAULT '' NOT NULL,
+fld5 char(35) DEFAULT '' NOT NULL,
+fld6 char(4) DEFAULT '' NOT NULL,
+UNIQUE fld1 (fld1),
+KEY fld3 (fld3),
+PRIMARY KEY (auto)
+);
+select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
+fld3
+imaginable
+select fld3 from t2 where fld3 like "%cultivation" ;
+fld3
+cultivation
+select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
+fld3 companynr
+concoct 58
+druggists 58
+engrossing 58
+Eurydice 58
+exclaimers 58
+ferociousness 58
+hopelessness 58
+Huey 58
+imaginable 58
+judges 58
+merging 58
+ostrich 58
+peering 58
+Phelps 58
+presumes 58
+Ruth 58
+sentences 58
+Shylock 58
+straggled 58
+synergy 58
+thanking 58
+tying 58
+unlocks 58
+select fld3,companynr from t2 where companynr = 58 order by fld3;
+fld3 companynr
+concoct 58
+druggists 58
+engrossing 58
+Eurydice 58
+exclaimers 58
+ferociousness 58
+hopelessness 58
+Huey 58
+imaginable 58
+judges 58
+merging 58
+ostrich 58
+peering 58
+Phelps 58
+presumes 58
+Ruth 58
+sentences 58
+Shylock 58
+straggled 58
+synergy 58
+thanking 58
+tying 58
+unlocks 58
+select fld3 from t2 order by fld3 desc limit 10;
+fld3
+youthfulness
+yelped
+Wotan
+workers
+Witt
+witchcraft
+Winsett
+Willy
+willed
+wildcats
+select fld3 from t2 order by fld3 desc limit 5;
+fld3
+youthfulness
+yelped
+Wotan
+workers
+Witt
+select fld3 from t2 order by fld3 desc limit 5,5;
+fld3
+witchcraft
+Winsett
+Willy
+willed
+wildcats
+select t2.fld3 from t2 where fld3 = 'honeysuckle';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'h%le';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
+fld3
+explain select t2.fld3 from t2 where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3,not_used);
+ERROR 42000: Key 'not_used' doesn't exist in table 't2'
+explain select fld3 from t2 use index (not_used);
+ERROR 42000: Key 'not_used' doesn't exist in table 't2'
+select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+fld3
+honeysuckle
+honoring
+explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld3 fld3 30 NULL 2 Using where; Using index
+select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
+fld1 fld3
+148504 Colombo
+068305 Colombo
+000000 nondecreasing
+select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes';
+fld1 fld3
+232605 appendixes
+1232605 appendixes
+1232606 appendixes
+1232607 appendixes
+1232608 appendixes
+1232609 appendixes
+select fld1 from t2 where fld1=250501 or fld1="250502";
+fld1
+250501
+250502
+explain select fld1 from t2 where fld1=250501 or fld1="250502";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld1 fld1 4 NULL 2 Using where; Using index
+select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
+fld1
+250501
+250502
+250505
+250601
+explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
+select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
+fld1 fld3
+012001 flanking
+013602 foldout
+013606 fingerings
+018007 fanatic
+018017 featherweight
+018054 fetters
+018103 flint
+018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
+188007 flurried
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
+226205 foothill
+226209 furnishings
+228306 forthcoming
+228311 fated
+231315 freezes
+232102 forgivably
+238007 filial
+238008 fixedly
+select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
+fld3
+select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
+fld3
+Chantilly
+select fld1,fld3 from t2 where fld1 like "25050%";
+fld1 fld3
+250501 poisoning
+250502 Iraqis
+250503 heaving
+250504 population
+250505 bomb
+select fld1,fld3 from t2 where fld1 like "25050_";
+fld1 fld3
+250501 poisoning
+250502 Iraqis
+250503 heaving
+250504 population
+250505 bomb
+select distinct companynr from t2;
+companynr
+00
+37
+36
+50
+58
+29
+40
+53
+65
+41
+34
+68
+select distinct companynr from t2 order by companynr;
+companynr
+00
+29
+34
+36
+37
+40
+41
+50
+53
+58
+65
+68
+select distinct companynr from t2 order by companynr desc;
+companynr
+68
+65
+58
+53
+50
+41
+40
+37
+36
+34
+29
+00
+select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%";
+fld3 period
+obliterates 9410
+offload 9410
+opaquely 9410
+organizer 9410
+overestimating 9410
+overlay 9410
+select distinct fld3 from t2 where companynr = 34 order by fld3;
+fld3
+absentee
+accessed
+ahead
+alphabetic
+Asiaticizations
+attitude
+aye
+bankruptcies
+belays
+Blythe
+bomb
+boulevard
+bulldozes
+cannot
+caressing
+charcoal
+checksumming
+chess
+clubroom
+colorful
+cosy
+creator
+crying
+Darius
+diffusing
+duality
+Eiffel
+Epiphany
+Ernestine
+explorers
+exterminated
+famine
+forked
+Gershwins
+heaving
+Hodges
+Iraqis
+Italianization
+Lagos
+landslide
+libretto
+Majorca
+mastering
+narrowed
+occurred
+offerers
+Palestine
+Peruvianizes
+pharmaceutic
+poisoning
+population
+Pygmalion
+rats
+realest
+recording
+regimented
+retransmitting
+reviver
+rouses
+scars
+sicker
+sleepwalk
+stopped
+sugars
+translatable
+uncles
+unexpected
+uprisings
+versatility
+vest
+select distinct fld3 from t2 limit 10;
+fld3
+abates
+abiding
+Abraham
+abrogating
+absentee
+abut
+accessed
+accruing
+accumulating
+accuracies
+select distinct fld3 from t2 having fld3 like "A%" limit 10;
+fld3
+abates
+abiding
+Abraham
+abrogating
+absentee
+abut
+accessed
+accruing
+accumulating
+accuracies
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%";
+substring(fld3,1,3)
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+Adl
+adm
+Ado
+ads
+adv
+aer
+aff
+afi
+afl
+afo
+agi
+ahe
+aim
+air
+Ald
+alg
+ali
+all
+alp
+alr
+ama
+ame
+amm
+ana
+and
+ane
+Ang
+ani
+Ann
+Ant
+api
+app
+aqu
+Ara
+arc
+Arm
+arr
+Art
+Asi
+ask
+asp
+ass
+ast
+att
+aud
+Aug
+aut
+ave
+avo
+awe
+aye
+Azt
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10;
+a
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10;
+substring(fld3,1,3)
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10;
+a
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+create table t3 (
+period int not null,
+name char(32) not null,
+companynr int not null,
+price double(11,0),
+price2 double(11,0),
+key (period),
+key (name)
+);
+create temporary table tmp engine = myisam select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+alter table t3 add t2nr int not null auto_increment primary key first;
+drop table tmp;
+SET SQL_BIG_TABLES=1;
+select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10;
+namn
+Abraham Abraham
+abrogating abrogating
+admonishing admonishing
+Adolph Adolph
+afield afield
+aging aging
+ammonium ammonium
+analyzable analyzable
+animals animals
+animized animized
+SET SQL_BIG_TABLES=0;
+select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10;
+concat(fld3," ",fld3)
+Abraham Abraham
+abrogating abrogating
+admonishing admonishing
+Adolph Adolph
+afield afield
+aging aging
+ammonium ammonium
+analyzable analyzable
+animals animals
+animized animized
+select distinct fld5 from t2 limit 10;
+fld5
+neat
+Steinberg
+jarring
+tinily
+balled
+persist
+attainments
+fanatic
+measures
+rightfulness
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
+fld3 count(*)
+affixed 1
+and 1
+annoyers 1
+Anthony 1
+assayed 1
+assurers 1
+attendants 1
+bedlam 1
+bedpost 1
+boasted 1
+SET SQL_BIG_TABLES=1;
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
+fld3 count(*)
+affixed 1
+and 1
+annoyers 1
+Anthony 1
+assayed 1
+assurers 1
+attendants 1
+bedlam 1
+bedpost 1
+boasted 1
+SET SQL_BIG_TABLES=0;
+select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10;
+fld3 repeat("a",length(fld3)) count(*)
+circus aaaaaa 1
+cited aaaaa 1
+Colombo aaaaaaa 1
+congresswoman aaaaaaaaaaaaa 1
+contrition aaaaaaaaaa 1
+corny aaaaa 1
+cultivation aaaaaaaaaaa 1
+definiteness aaaaaaaaaaaa 1
+demultiplex aaaaaaaaaaa 1
+disappointing aaaaaaaaaaaaa 1
+select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2;
+companynr rtrim(space(512+companynr))
+37
+78
+101
+154
+311
+447
+512
+select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3;
+fld3
+explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
+1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer (flat, BKA join)
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
+1 SIMPLE t1 ref period period 4 test.t3.period 4181 Using join buffer (flat, BKA join)
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
+1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer (flat, BKA join)
+select period from t1;
+period
+9410
+select period from t1 where period=1900;
+period
+select fld3,period from t1,t2 where fld1 = 011401 order by period;
+fld3 period
+breaking 9410
+select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001;
+fld3 period
+breaking 1001
+explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 const fld1 fld1 4 const 1
+1 SIMPLE t3 const PRIMARY,period PRIMARY 4 const 1
+select fld3,period from t2,t1 where companynr*10 = 37*10;
+fld3 period
+breaking 9410
+Romans 9410
+intercepted 9410
+bewilderingly 9410
+astound 9410
+admonishing 9410
+sumac 9410
+flanking 9410
+combed 9410
+subjective 9410
+scatterbrain 9410
+Eulerian 9410
+Kane 9410
+overlay 9410
+perturb 9410
+goblins 9410
+annihilates 9410
+Wotan 9410
+snatching 9410
+concludes 9410
+laterally 9410
+yelped 9410
+grazing 9410
+Baird 9410
+celery 9410
+misunderstander 9410
+handgun 9410
+foldout 9410
+mystic 9410
+succumbed 9410
+Nabisco 9410
+fingerings 9410
+aging 9410
+afield 9410
+ammonium 9410
+boat 9410
+intelligibility 9410
+Augustine 9410
+teethe 9410
+dreaded 9410
+scholastics 9410
+audiology 9410
+wallet 9410
+parters 9410
+eschew 9410
+quitter 9410
+neat 9410
+Steinberg 9410
+jarring 9410
+tinily 9410
+balled 9410
+persist 9410
+attainments 9410
+fanatic 9410
+measures 9410
+rightfulness 9410
+capably 9410
+impulsive 9410
+starlet 9410
+terminators 9410
+untying 9410
+announces 9410
+featherweight 9410
+pessimist 9410
+daughter 9410
+decliner 9410
+lawgiver 9410
+stated 9410
+readable 9410
+attrition 9410
+cascade 9410
+motors 9410
+interrogate 9410
+pests 9410
+stairway 9410
+dopers 9410
+testicle 9410
+Parsifal 9410
+leavings 9410
+postulation 9410
+squeaking 9410
+contrasted 9410
+leftover 9410
+whiteners 9410
+erases 9410
+Punjab 9410
+Merritt 9410
+Quixotism 9410
+sweetish 9410
+dogging 9410
+scornfully 9410
+bellow 9410
+bills 9410
+cupboard 9410
+sureties 9410
+puddings 9410
+fetters 9410
+bivalves 9410
+incurring 9410
+Adolph 9410
+pithed 9410
+Miles 9410
+trimmings 9410
+tragedies 9410
+skulking 9410
+flint 9410
+flopping 9410
+relaxing 9410
+offload 9410
+suites 9410
+lists 9410
+animized 9410
+multilayer 9410
+standardizes 9410
+Judas 9410
+vacuuming 9410
+dentally 9410
+humanness 9410
+inch 9410
+Weissmuller 9410
+irresponsibly 9410
+luckily 9410
+culled 9410
+medical 9410
+bloodbath 9410
+subschema 9410
+animals 9410
+Micronesia 9410
+repetitions 9410
+Antares 9410
+ventilate 9410
+pityingly 9410
+interdependent 9410
+Graves 9410
+neonatal 9410
+chafe 9410
+honoring 9410
+realtor 9410
+elite 9410
+funereal 9410
+abrogating 9410
+sorters 9410
+Conley 9410
+lectured 9410
+Abraham 9410
+Hawaii 9410
+cage 9410
+hushes 9410
+Simla 9410
+reporters 9410
+Dutchman 9410
+descendants 9410
+groupings 9410
+dissociate 9410
+coexist 9410
+Beebe 9410
+Taoism 9410
+Connally 9410
+fetched 9410
+checkpoints 9410
+rusting 9410
+galling 9410
+obliterates 9410
+traitor 9410
+resumes 9410
+analyzable 9410
+terminator 9410
+gritty 9410
+firearm 9410
+minima 9410
+Selfridge 9410
+disable 9410
+witchcraft 9410
+betroth 9410
+Manhattanize 9410
+imprint 9410
+peeked 9410
+swelling 9410
+interrelationships 9410
+riser 9410
+Gandhian 9410
+peacock 9410
+bee 9410
+kanji 9410
+dental 9410
+scarf 9410
+chasm 9410
+insolence 9410
+syndicate 9410
+alike 9410
+imperial 9410
+convulsion 9410
+railway 9410
+validate 9410
+normalizes 9410
+comprehensive 9410
+chewing 9410
+denizen 9410
+schemer 9410
+chronicle 9410
+Kline 9410
+Anatole 9410
+partridges 9410
+brunch 9410
+recruited 9410
+dimensions 9410
+Chicana 9410
+announced 9410
+praised 9410
+employing 9410
+linear 9410
+quagmire 9410
+western 9410
+relishing 9410
+serving 9410
+scheduling 9410
+lore 9410
+eventful 9410
+arteriole 9410
+disentangle 9410
+cured 9410
+Fenton 9410
+avoidable 9410
+drains 9410
+detectably 9410
+husky 9410
+impelling 9410
+undoes 9410
+evened 9410
+squeezes 9410
+destroyer 9410
+rudeness 9410
+beaner 9410
+boorish 9410
+Everhart 9410
+encompass 9410
+mushrooms 9410
+Alison 9410
+externally 9410
+pellagra 9410
+cult 9410
+creek 9410
+Huffman 9410
+Majorca 9410
+governing 9410
+gadfly 9410
+reassigned 9410
+intentness 9410
+craziness 9410
+psychic 9410
+squabbled 9410
+burlesque 9410
+capped 9410
+extracted 9410
+DiMaggio 9410
+exclamation 9410
+subdirectory 9410
+Gothicism 9410
+feminine 9410
+metaphysically 9410
+sanding 9410
+Miltonism 9410
+freakish 9410
+index 9410
+straight 9410
+flurried 9410
+denotative 9410
+coming 9410
+commencements 9410
+gentleman 9410
+gifted 9410
+Shanghais 9410
+sportswriting 9410
+sloping 9410
+navies 9410
+leaflet 9410
+shooter 9410
+Joplin 9410
+babies 9410
+assails 9410
+admiring 9410
+swaying 9410
+Goldstine 9410
+fitting 9410
+Norwalk 9410
+analogy 9410
+deludes 9410
+cokes 9410
+Clayton 9410
+exhausts 9410
+causality 9410
+sating 9410
+icon 9410
+throttles 9410
+communicants 9410
+dehydrate 9410
+priceless 9410
+publicly 9410
+incidentals 9410
+commonplace 9410
+mumbles 9410
+furthermore 9410
+cautioned 9410
+parametrized 9410
+registration 9410
+sadly 9410
+positioning 9410
+babysitting 9410
+eternal 9410
+hoarder 9410
+congregates 9410
+rains 9410
+workers 9410
+sags 9410
+unplug 9410
+garage 9410
+boulder 9410
+specifics 9410
+Teresa 9410
+Winsett 9410
+convenient 9410
+buckboards 9410
+amenities 9410
+resplendent 9410
+sews 9410
+participated 9410
+Simon 9410
+certificates 9410
+Fitzpatrick 9410
+Evanston 9410
+misted 9410
+textures 9410
+save 9410
+count 9410
+rightful 9410
+chaperone 9410
+Lizzy 9410
+clenched 9410
+effortlessly 9410
+accessed 9410
+beaters 9410
+Hornblower 9410
+vests 9410
+indulgences 9410
+infallibly 9410
+unwilling 9410
+excrete 9410
+spools 9410
+crunches 9410
+overestimating 9410
+ineffective 9410
+humiliation 9410
+sophomore 9410
+star 9410
+rifles 9410
+dialysis 9410
+arriving 9410
+indulge 9410
+clockers 9410
+languages 9410
+Antarctica 9410
+percentage 9410
+ceiling 9410
+specification 9410
+regimented 9410
+ciphers 9410
+pictures 9410
+serpents 9410
+allot 9410
+realized 9410
+mayoral 9410
+opaquely 9410
+hostess 9410
+fiftieth 9410
+incorrectly 9410
+decomposition 9410
+stranglings 9410
+mixture 9410
+electroencephalography 9410
+similarities 9410
+charges 9410
+freest 9410
+Greenberg 9410
+tinting 9410
+expelled 9410
+warm 9410
+smoothed 9410
+deductions 9410
+Romano 9410
+bitterroot 9410
+corset 9410
+securing 9410
+environing 9410
+cute 9410
+Crays 9410
+heiress 9410
+inform 9410
+avenge 9410
+universals 9410
+Kinsey 9410
+ravines 9410
+bestseller 9410
+equilibrium 9410
+extents 9410
+relatively 9410
+pressure 9410
+critiques 9410
+befouled 9410
+rightfully 9410
+mechanizing 9410
+Latinizes 9410
+timesharing 9410
+Aden 9410
+embassies 9410
+males 9410
+shapelessly 9410
+mastering 9410
+Newtonian 9410
+finishers 9410
+abates 9410
+teem 9410
+kiting 9410
+stodgy 9410
+feed 9410
+guitars 9410
+airships 9410
+store 9410
+denounces 9410
+Pyle 9410
+Saxony 9410
+serializations 9410
+Peruvian 9410
+taxonomically 9410
+kingdom 9410
+stint 9410
+Sault 9410
+faithful 9410
+Ganymede 9410
+tidiness 9410
+gainful 9410
+contrary 9410
+Tipperary 9410
+tropics 9410
+theorizers 9410
+renew 9410
+already 9410
+terminal 9410
+Hegelian 9410
+hypothesizer 9410
+warningly 9410
+journalizing 9410
+nested 9410
+Lars 9410
+saplings 9410
+foothill 9410
+labeled 9410
+imperiously 9410
+reporters 9410
+furnishings 9410
+precipitable 9410
+discounts 9410
+excises 9410
+Stalin 9410
+despot 9410
+ripeness 9410
+Arabia 9410
+unruly 9410
+mournfulness 9410
+boom 9410
+slaughter 9410
+Sabine 9410
+handy 9410
+rural 9410
+organizer 9410
+shipyard 9410
+civics 9410
+inaccuracy 9410
+rules 9410
+juveniles 9410
+comprised 9410
+investigations 9410
+stabilizes 9410
+seminaries 9410
+Hunter 9410
+sporty 9410
+test 9410
+weasels 9410
+CERN 9410
+tempering 9410
+afore 9410
+Galatean 9410
+techniques 9410
+error 9410
+veranda 9410
+severely 9410
+Cassites 9410
+forthcoming 9410
+guides 9410
+vanish 9410
+lied 9410
+sawtooth 9410
+fated 9410
+gradually 9410
+widens 9410
+preclude 9410
+evenhandedly 9410
+percentage 9410
+disobedience 9410
+humility 9410
+gleaning 9410
+petted 9410
+bloater 9410
+minion 9410
+marginal 9410
+apiary 9410
+measures 9410
+precaution 9410
+repelled 9410
+primary 9410
+coverings 9410
+Artemia 9410
+navigate 9410
+spatial 9410
+Gurkha 9410
+meanwhile 9410
+Melinda 9410
+Butterfield 9410
+Aldrich 9410
+previewing 9410
+glut 9410
+unaffected 9410
+inmate 9410
+mineral 9410
+impending 9410
+meditation 9410
+ideas 9410
+miniaturizes 9410
+lewdly 9410
+title 9410
+youthfulness 9410
+creak 9410
+Chippewa 9410
+clamored 9410
+freezes 9410
+forgivably 9410
+reduce 9410
+McGovern 9410
+Nazis 9410
+epistle 9410
+socializes 9410
+conceptions 9410
+Kevin 9410
+uncovering 9410
+chews 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+raining 9410
+infest 9410
+compartment 9410
+minting 9410
+ducks 9410
+roped 9410
+waltz 9410
+Lillian 9410
+repressions 9410
+chillingly 9410
+noncritical 9410
+lithograph 9410
+spongers 9410
+parenthood 9410
+posed 9410
+instruments 9410
+filial 9410
+fixedly 9410
+relives 9410
+Pandora 9410
+watering 9410
+ungrateful 9410
+secures 9410
+poison 9410
+dusted 9410
+encompasses 9410
+presentation 9410
+Kantian 9410
+select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price;
+fld3 period price price2
+admonishing 1002 28357832 8723648
+analyzable 1002 28357832 8723648
+annihilates 1001 5987435 234724
+Antares 1002 28357832 8723648
+astound 1001 5987435 234724
+audiology 1001 5987435 234724
+Augustine 1002 28357832 8723648
+Baird 1002 28357832 8723648
+bewilderingly 1001 5987435 234724
+breaking 1001 5987435 234724
+Conley 1001 5987435 234724
+dentally 1002 28357832 8723648
+dissociate 1002 28357832 8723648
+elite 1001 5987435 234724
+eschew 1001 5987435 234724
+Eulerian 1001 5987435 234724
+flanking 1001 5987435 234724
+foldout 1002 28357832 8723648
+funereal 1002 28357832 8723648
+galling 1002 28357832 8723648
+Graves 1001 5987435 234724
+grazing 1001 5987435 234724
+groupings 1001 5987435 234724
+handgun 1001 5987435 234724
+humility 1002 28357832 8723648
+impulsive 1002 28357832 8723648
+inch 1001 5987435 234724
+intelligibility 1001 5987435 234724
+jarring 1001 5987435 234724
+lawgiver 1001 5987435 234724
+lectured 1002 28357832 8723648
+Merritt 1002 28357832 8723648
+neonatal 1001 5987435 234724
+offload 1002 28357832 8723648
+parters 1002 28357832 8723648
+pityingly 1002 28357832 8723648
+puddings 1002 28357832 8723648
+Punjab 1001 5987435 234724
+quitter 1002 28357832 8723648
+realtor 1001 5987435 234724
+relaxing 1001 5987435 234724
+repetitions 1001 5987435 234724
+resumes 1001 5987435 234724
+Romans 1002 28357832 8723648
+rusting 1001 5987435 234724
+scholastics 1001 5987435 234724
+skulking 1002 28357832 8723648
+stated 1002 28357832 8723648
+suites 1002 28357832 8723648
+sureties 1001 5987435 234724
+testicle 1002 28357832 8723648
+tinily 1002 28357832 8723648
+tragedies 1001 5987435 234724
+trimmings 1001 5987435 234724
+vacuuming 1001 5987435 234724
+ventilate 1001 5987435 234724
+wallet 1001 5987435 234724
+Weissmuller 1002 28357832 8723648
+Wotan 1002 28357832 8723648
+select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37;
+fld1 fld3 period price price2
+018201 relaxing 1001 5987435 234724
+018601 vacuuming 1001 5987435 234724
+018801 inch 1001 5987435 234724
+018811 repetitions 1001 5987435 234724
+create table t4 (
+companynr tinyint(2) unsigned zerofill NOT NULL default '00',
+companyname char(30) NOT NULL default '',
+PRIMARY KEY (companynr),
+UNIQUE KEY companyname(companyname)
+) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames';
+select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
+companynr companyname
+00 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
+companynr companyname
+00 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select * from t1,t1 t12;
+Period Varor_period Period Varor_period
+9410 9412 9410 9412
+select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505;
+fld1 fld1
+250501 250501
+250502 250501
+250503 250501
+250504 250501
+250505 250501
+250501 250502
+250502 250502
+250503 250502
+250504 250502
+250505 250502
+250501 250503
+250502 250503
+250503 250503
+250504 250503
+250505 250503
+250501 250504
+250502 250504
+250503 250504
+250504 250504
+250505 250504
+250501 250505
+250502 250505
+250503 250505
+250504 250505
+250505 250505
+insert into t2 (fld1, companynr) values (999999,99);
+select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+companynr companyname
+99 NULL
+select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null;
+count(*)
+1199
+explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1200
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists; Using join buffer (flat, BKA join)
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists; Using join buffer (flat, BNL join)
+select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
+companynr companyname
+select count(*) from t2 left join t4 using (companynr) where companynr is not null;
+count(*)
+1200
+explain select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+delete from t2 where fld1=999999;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join)
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join)
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join)
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
+companynr companynr
+37 36
+41 40
+explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909);
+period
+9410
+select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6)));
+period
+9410
+select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1;
+fld1
+250501
+250502
+250503
+250505
+select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606);
+fld1
+250502
+250503
+select fld1 from t2 where fld1 between 250502 and 250504;
+fld1
+250502
+250503
+250504
+select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ;
+fld3
+label
+labeled
+labeled
+landslide
+laterally
+leaflet
+lewdly
+Lillian
+luckily
+select count(*) from t1;
+count(*)
+1
+select companynr,count(*),sum(fld1) from t2 group by companynr;
+companynr count(*) sum(fld1)
+00 82 10355753
+29 95 14473298
+34 70 17788966
+36 215 22786296
+37 588 83602098
+40 37 6618386
+41 52 12816335
+50 11 1595438
+53 4 793210
+58 23 2254293
+65 10 2284055
+68 12 3097288
+select companynr,count(*) from t2 group by companynr order by companynr desc limit 5;
+companynr count(*)
+68 12
+65 10
+58 23
+53 4
+50 11
+select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
+count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
+70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
+explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
+Warnings:
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
+select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
+companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
+00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
+29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026
+34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
+select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
+companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
+37 1 1 5987435 5987435 5987435 5987435.0000
+37 2 1 28357832 28357832 28357832 28357832.0000
+37 3 1 39654943 39654943 39654943 39654943.0000
+37 11 1 5987435 5987435 5987435 5987435.0000
+37 12 1 28357832 28357832 28357832 28357832.0000
+37 13 1 39654943 39654943 39654943 39654943.0000
+37 21 1 5987435 5987435 5987435 5987435.0000
+37 22 1 28357832 28357832 28357832 28357832.0000
+37 23 1 39654943 39654943 39654943 39654943.0000
+37 31 1 5987435 5987435 5987435 5987435.0000
+select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
+companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
+37 1 1 5987435 5987435 5987435 5987435.0000
+37 2 1 28357832 28357832 28357832 28357832.0000
+37 3 1 39654943 39654943 39654943 39654943.0000
+37 11 1 5987435 5987435 5987435 5987435.0000
+37 12 1 28357832 28357832 28357832 28357832.0000
+37 13 1 39654943 39654943 39654943 39654943.0000
+37 21 1 5987435 5987435 5987435 5987435.0000
+37 22 1 28357832 28357832 28357832 28357832.0000
+37 23 1 39654943 39654943 39654943 39654943.0000
+37 31 1 5987435 5987435 5987435 5987435.0000
+select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;
+companynr count(price) sum(price) min(price) max(price) avg(price)
+37 12543 309394878010 5987435 39654943 24666736.6667
+78 8362 414611089292 726498 98439034 49582766.0000
+101 4181 3489454238 834598 834598 834598.0000
+154 4181 4112197254950 983543950 983543950 983543950.0000
+311 4181 979599938 234298 234298 234298.0000
+447 4181 9929180954 2374834 2374834 2374834.0000
+512 4181 3288532102 786542 786542 786542.0000
+select distinct mod(companynr,10) from t4 group by companynr;
+mod(companynr,10)
+0
+9
+4
+6
+7
+1
+3
+8
+5
+select distinct 1 from t4 group by companynr;
+1
+1
+select count(distinct fld1) from t2;
+count(distinct fld1)
+1199
+select companynr,count(distinct fld1) from t2 group by companynr;
+companynr count(distinct fld1)
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(*) from t2 group by companynr;
+companynr count(*)
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr;
+companynr count(distinct concat(fld1,repeat(65,1000)))
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr;
+companynr count(distinct concat(fld1,repeat(65,200)))
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct floor(fld1/100)) from t2 group by companynr;
+companynr count(distinct floor(fld1/100))
+00 47
+29 35
+34 14
+36 69
+37 108
+40 16
+41 11
+50 9
+53 1
+58 1
+65 1
+68 1
+select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr;
+companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
+00 47
+29 35
+34 14
+36 69
+37 108
+40 16
+41 11
+50 9
+53 1
+58 1
+65 1
+68 1
+select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10;
+sum(fld1) fld3
+11402 Romans
+select name,count(*) from t3 where name='cloakroom' group by name;
+name count(*)
+cloakroom 4181
+select name,count(*) from t3 where name='cloakroom' and price>10 group by name;
+name count(*)
+cloakroom 4181
+select count(*) from t3 where name='cloakroom' and price2=823742;
+count(*)
+4181
+select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name;
+name count(*)
+cloakroom 4181
+select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name;
+name count(*)
+extramarital 4181
+gazer 4181
+gems 4181
+Iranizes 4181
+spates 4181
+tucked 4181
+violinist 4181
+select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
+fld3 count(*)
+spates 4181
+select companynr|0,companyname from t4 group by 1;
+companynr|0 companyname
+0 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname;
+companynr companyname count(*)
+29 company 1 95
+68 company 10 12
+50 company 11 11
+34 company 2 70
+36 company 3 215
+37 company 4 588
+40 company 5 37
+41 company 6 52
+53 company 7 4
+58 company 8 23
+65 company 9 10
+00 Unknown 82
+select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
+fld1 count(*)
+158402 4181
+select sum(Period)/count(*) from t1;
+sum(Period)/count(*)
+9410.0000
+select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr;
+companynr count sum diff func
+37 12543 309394878010 0.0000 464091
+78 8362 414611089292 0.0000 652236
+101 4181 3489454238 0.0000 422281
+154 4181 4112197254950 0.0000 643874
+311 4181 979599938 0.0000 1300291
+447 4181 9929180954 0.0000 1868907
+512 4181 3288532102 0.0000 2140672
+select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg;
+companynr avg
+154 983543950.0000
+select companynr,count(*) from t2 group by companynr order by 2 desc;
+companynr count(*)
+37 588
+36 215
+29 95
+00 82
+34 70
+41 52
+40 37
+58 23
+68 12
+50 11
+65 10
+53 4
+select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc;
+companynr count(*)
+41 52
+58 23
+68 12
+50 11
+65 10
+53 4
+select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4;
+fld4 fld1 count(price) sum(price) min(price) max(price) avg(price)
+teethe 000001 1 5987435 5987435 5987435 5987435.0000
+dreaded 011401 1 5987435 5987435 5987435 5987435.0000
+scholastics 011402 1 28357832 28357832 28357832 28357832.0000
+audiology 011403 1 39654943 39654943 39654943 39654943.0000
+wallet 011501 1 5987435 5987435 5987435 5987435.0000
+parters 011701 1 5987435 5987435 5987435 5987435.0000
+eschew 011702 1 28357832 28357832 28357832 28357832.0000
+quitter 011703 1 39654943 39654943 39654943 39654943.0000
+neat 012001 1 5987435 5987435 5987435 5987435.0000
+Steinberg 012003 1 39654943 39654943 39654943 39654943.0000
+balled 012301 1 5987435 5987435 5987435 5987435.0000
+persist 012302 1 28357832 28357832 28357832 28357832.0000
+attainments 012303 1 39654943 39654943 39654943 39654943.0000
+capably 012501 1 5987435 5987435 5987435 5987435.0000
+impulsive 012602 1 28357832 28357832 28357832 28357832.0000
+starlet 012603 1 39654943 39654943 39654943 39654943.0000
+featherweight 012701 1 5987435 5987435 5987435 5987435.0000
+pessimist 012702 1 28357832 28357832 28357832 28357832.0000
+daughter 012703 1 39654943 39654943 39654943 39654943.0000
+lawgiver 013601 1 5987435 5987435 5987435 5987435.0000
+stated 013602 1 28357832 28357832 28357832 28357832.0000
+readable 013603 1 39654943 39654943 39654943 39654943.0000
+testicle 013801 1 5987435 5987435 5987435 5987435.0000
+Parsifal 013802 1 28357832 28357832 28357832 28357832.0000
+leavings 013803 1 39654943 39654943 39654943 39654943.0000
+squeaking 013901 1 5987435 5987435 5987435 5987435.0000
+contrasted 016001 1 5987435 5987435 5987435 5987435.0000
+leftover 016201 1 5987435 5987435 5987435 5987435.0000
+whiteners 016202 1 28357832 28357832 28357832 28357832.0000
+erases 016301 1 5987435 5987435 5987435 5987435.0000
+Punjab 016302 1 28357832 28357832 28357832 28357832.0000
+Merritt 016303 1 39654943 39654943 39654943 39654943.0000
+sweetish 018001 1 5987435 5987435 5987435 5987435.0000
+dogging 018002 1 28357832 28357832 28357832 28357832.0000
+scornfully 018003 1 39654943 39654943 39654943 39654943.0000
+fetters 018012 1 28357832 28357832 28357832 28357832.0000
+bivalves 018013 1 39654943 39654943 39654943 39654943.0000
+skulking 018021 1 5987435 5987435 5987435 5987435.0000
+flint 018022 1 28357832 28357832 28357832 28357832.0000
+flopping 018023 1 39654943 39654943 39654943 39654943.0000
+Judas 018032 1 28357832 28357832 28357832 28357832.0000
+vacuuming 018033 1 39654943 39654943 39654943 39654943.0000
+medical 018041 1 5987435 5987435 5987435 5987435.0000
+bloodbath 018042 1 28357832 28357832 28357832 28357832.0000
+subschema 018043 1 39654943 39654943 39654943 39654943.0000
+interdependent 018051 1 5987435 5987435 5987435 5987435.0000
+Graves 018052 1 28357832 28357832 28357832 28357832.0000
+neonatal 018053 1 39654943 39654943 39654943 39654943.0000
+sorters 018061 1 5987435 5987435 5987435 5987435.0000
+epistle 018062 1 28357832 28357832 28357832 28357832.0000
+Conley 018101 1 5987435 5987435 5987435 5987435.0000
+lectured 018102 1 28357832 28357832 28357832 28357832.0000
+Abraham 018103 1 39654943 39654943 39654943 39654943.0000
+cage 018201 1 5987435 5987435 5987435 5987435.0000
+hushes 018202 1 28357832 28357832 28357832 28357832.0000
+Simla 018402 1 28357832 28357832 28357832 28357832.0000
+reporters 018403 1 39654943 39654943 39654943 39654943.0000
+coexist 018601 1 5987435 5987435 5987435 5987435.0000
+Beebe 018602 1 28357832 28357832 28357832 28357832.0000
+Taoism 018603 1 39654943 39654943 39654943 39654943.0000
+Connally 018801 1 5987435 5987435 5987435 5987435.0000
+fetched 018802 1 28357832 28357832 28357832 28357832.0000
+checkpoints 018803 1 39654943 39654943 39654943 39654943.0000
+gritty 018811 1 5987435 5987435 5987435 5987435.0000
+firearm 018812 1 28357832 28357832 28357832 28357832.0000
+minima 019101 1 5987435 5987435 5987435 5987435.0000
+Selfridge 019102 1 28357832 28357832 28357832 28357832.0000
+disable 019103 1 39654943 39654943 39654943 39654943.0000
+witchcraft 019201 1 5987435 5987435 5987435 5987435.0000
+betroth 030501 1 5987435 5987435 5987435 5987435.0000
+Manhattanize 030502 1 28357832 28357832 28357832 28357832.0000
+imprint 030503 1 39654943 39654943 39654943 39654943.0000
+swelling 031901 1 5987435 5987435 5987435 5987435.0000
+interrelationships 036001 1 5987435 5987435 5987435 5987435.0000
+riser 036002 1 28357832 28357832 28357832 28357832.0000
+bee 038001 1 5987435 5987435 5987435 5987435.0000
+kanji 038002 1 28357832 28357832 28357832 28357832.0000
+dental 038003 1 39654943 39654943 39654943 39654943.0000
+railway 038011 1 5987435 5987435 5987435 5987435.0000
+validate 038012 1 28357832 28357832 28357832 28357832.0000
+normalizes 038013 1 39654943 39654943 39654943 39654943.0000
+Kline 038101 1 5987435 5987435 5987435 5987435.0000
+Anatole 038102 1 28357832 28357832 28357832 28357832.0000
+partridges 038103 1 39654943 39654943 39654943 39654943.0000
+recruited 038201 1 5987435 5987435 5987435 5987435.0000
+dimensions 038202 1 28357832 28357832 28357832 28357832.0000
+Chicana 038203 1 39654943 39654943 39654943 39654943.0000
+select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3;
+companynr fld3 sum(price)
+512 boat 786542
+512 capably 786542
+512 cupboard 786542
+512 decliner 786542
+512 descendants 786542
+512 dopers 786542
+512 erases 786542
+512 Micronesia 786542
+512 Miles 786542
+512 skies 786542
+select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr;
+companynr count(*) min(fld3) max(fld3) sum(price) avg(price)
+00 1 Omaha Omaha 5987435 5987435.0000
+36 1 dubbed dubbed 28357832 28357832.0000
+37 83 Abraham Wotan 1908978016 22999735.1325
+50 2 scribbled tapestry 68012775 34006387.5000
+select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1;
+t3.companynr+0 t2nr fld3 sum(price)
+37 1 Omaha 5987435
+37 11401 breaking 5987435
+37 11402 Romans 28357832
+37 11403 intercepted 39654943
+37 11501 bewilderingly 5987435
+37 11701 astound 5987435
+37 11702 admonishing 28357832
+37 11703 sumac 39654943
+37 12001 flanking 5987435
+37 12003 combed 39654943
+37 12301 Eulerian 5987435
+37 12302 dubbed 28357832
+37 12303 Kane 39654943
+37 12501 annihilates 5987435
+37 12602 Wotan 28357832
+37 12603 snatching 39654943
+37 12701 grazing 5987435
+37 12702 Baird 28357832
+37 12703 celery 39654943
+37 13601 handgun 5987435
+37 13602 foldout 28357832
+37 13603 mystic 39654943
+37 13801 intelligibility 5987435
+37 13802 Augustine 28357832
+37 13803 teethe 39654943
+37 13901 scholastics 5987435
+37 16001 audiology 5987435
+37 16201 wallet 5987435
+37 16202 parters 28357832
+37 16301 eschew 5987435
+37 16302 quitter 28357832
+37 16303 neat 39654943
+37 18001 jarring 5987435
+37 18002 tinily 28357832
+37 18003 balled 39654943
+37 18012 impulsive 28357832
+37 18013 starlet 39654943
+37 18021 lawgiver 5987435
+37 18022 stated 28357832
+37 18023 readable 39654943
+37 18032 testicle 28357832
+37 18033 Parsifal 39654943
+37 18041 Punjab 5987435
+37 18042 Merritt 28357832
+37 18043 Quixotism 39654943
+37 18051 sureties 5987435
+37 18052 puddings 28357832
+37 18053 tapestry 39654943
+37 18061 trimmings 5987435
+37 18062 humility 28357832
+37 18101 tragedies 5987435
+37 18102 skulking 28357832
+37 18103 flint 39654943
+37 18201 relaxing 5987435
+37 18202 offload 28357832
+37 18402 suites 28357832
+37 18403 lists 39654943
+37 18601 vacuuming 5987435
+37 18602 dentally 28357832
+37 18603 humanness 39654943
+37 18801 inch 5987435
+37 18802 Weissmuller 28357832
+37 18803 irresponsibly 39654943
+37 18811 repetitions 5987435
+37 18812 Antares 28357832
+37 19101 ventilate 5987435
+37 19102 pityingly 28357832
+37 19103 interdependent 39654943
+37 19201 Graves 5987435
+37 30501 neonatal 5987435
+37 30502 scribbled 28357832
+37 30503 chafe 39654943
+37 31901 realtor 5987435
+37 36001 elite 5987435
+37 36002 funereal 28357832
+37 38001 Conley 5987435
+37 38002 lectured 28357832
+37 38003 Abraham 39654943
+37 38011 groupings 5987435
+37 38012 dissociate 28357832
+37 38013 coexist 39654943
+37 38101 rusting 5987435
+37 38102 galling 28357832
+37 38103 obliterates 39654943
+37 38201 resumes 5987435
+37 38202 analyzable 28357832
+37 38203 terminator 39654943
+select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008;
+sum(price)
+234298
+select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1;
+fld1 sum(price)
+038008 234298
+explain select fld3 from t2 where 1>2 or 2>3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select fld3 from t2 where fld1=fld1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;
+companynr fld1
+34 250501
+34 250502
+select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502;
+companynr fld1
+34 250501
+34 250502
+select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000;
+companynr count sum
+00 82 10355753
+29 95 14473298
+34 70 17788966
+37 588 83602098
+41 52 12816335
+select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ;
+companynr
+00
+29
+34
+37
+41
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40;
+companynr companyname count(*)
+68 company 10 12
+50 company 11 11
+40 company 5 37
+41 company 6 52
+53 company 7 4
+58 company 8 23
+65 company 9 10
+select count(*) from t2;
+count(*)
+1199
+select count(*) from t2 where fld1 < 098024;
+count(*)
+387
+select min(fld1) from t2 where fld1>= 098024;
+min(fld1)
+98024
+select max(fld1) from t2 where fld1>= 098024;
+max(fld1)
+1232609
+select count(*) from t3 where price2=76234234;
+count(*)
+4181
+select count(*) from t3 where companynr=512 and price2=76234234;
+count(*)
+4181
+explain select min(fld1),max(fld1),count(*) from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+select min(fld1),max(fld1),count(*) from t2;
+min(fld1) max(fld1) count(*)
+0 1232609 1199
+select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742;
+min(t2nr) max(t2nr)
+2115 2115
+select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78;
+count(*) min(t2nr) max(t2nr)
+4181 4 41804
+select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20;
+t2nr count(*)
+9 1
+19 1
+29 1
+39 1
+49 1
+59 1
+69 1
+79 1
+89 1
+99 1
+109 1
+119 1
+129 1
+139 1
+149 1
+159 1
+169 1
+179 1
+189 1
+199 1
+select max(t2nr) from t3 where price=983543950;
+max(t2nr)
+41807
+select t1.period from t3 = t1 limit 1;
+period
+1001
+select t1.period from t1 as t1 limit 1;
+period
+9410
+select t1.period as "Nuvarande period" from t1 as t1 limit 1;
+Nuvarande period
+9410
+select period as ok_period from t1 limit 1;
+ok_period
+9410
+select period as ok_period from t1 group by ok_period limit 1;
+ok_period
+9410
+select 1+1 as summa from t1 group by summa limit 1;
+summa
+2
+select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1;
+Nuvarande period
+9410
+show tables;
+Tables_in_test
+t1
+t2
+t3
+t4
+show tables from test like "s%";
+Tables_in_test (s%)
+show tables from test like "t?";
+Tables_in_test (t?)
+show full columns from t2;
+Field Type Collation Null Key Default Extra Privileges Comment
+auto int(11) NULL NO PRI NULL auto_increment #
+fld1 int(6) unsigned zerofill NULL NO UNI 000000 #
+companynr tinyint(2) unsigned zerofill NULL NO 00 #
+fld3 char(30) latin1_swedish_ci NO MUL #
+fld4 char(35) latin1_swedish_ci NO #
+fld5 char(35) latin1_swedish_ci NO #
+fld6 char(4) latin1_swedish_ci NO #
+show full columns from t2 from test like 'f%';
+Field Type Collation Null Key Default Extra Privileges Comment
+fld1 int(6) unsigned zerofill NULL NO UNI 000000 #
+fld3 char(30) latin1_swedish_ci NO MUL #
+fld4 char(35) latin1_swedish_ci NO #
+fld5 char(35) latin1_swedish_ci NO #
+fld6 char(4) latin1_swedish_ci NO #
+show full columns from t2 from test like 's%';
+Field Type Collation Null Key Default Extra Privileges Comment
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
+t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
+t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
+drop table t4, t3, t2, t1;
+DO 1;
+DO benchmark(100,1+1),1,1;
+do default;
+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 '' at line 1
+do foobar;
+ERROR 42S22: Unknown column 'foobar' in 'field list'
+CREATE TABLE t1 (
+id mediumint(8) unsigned NOT NULL auto_increment,
+pseudo varchar(35) NOT NULL default '',
+PRIMARY KEY (id),
+UNIQUE KEY pseudo (pseudo)
+);
+INSERT INTO t1 (pseudo) VALUES ('test');
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 1 as rnd1 from t1 where rand() > 2;
+rnd1
+DROP TABLE t1;
+CREATE TABLE t1 (gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
+CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'wrong-date-value' AND b.sampletime < 'wrong-date-value' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+gvid the_success the_fail the_size the_time
+Warnings:
+Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1
+Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= NULL AND b.sampletime < NULL AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+gvid the_success the_fail the_size the_time
+DROP TABLE t1,t2;
+create table t1 ( A_Id bigint(20) NOT NULL default '0', A_UpdateBy char(10) NOT NULL default '', A_UpdateDate bigint(20) NOT NULL default '0', A_UpdateSerial int(11) NOT NULL default '0', other_types bigint(20) NOT NULL default '0', wss_type bigint(20) NOT NULL default '0');
+INSERT INTO t1 VALUES (102935998719055004,'brade',1029359987,2,102935229116544068,102935229216544093);
+select wss_type from t1 where wss_type ='102935229216544106';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544105';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544104';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544093';
+wss_type
+102935229216544093
+select wss_type from t1 where wss_type =102935229216544093;
+wss_type
+102935229216544093
+drop table t1;
+select 1+2,"aaaa",3.13*2.0 into @a,@b,@c;
+select @a;
+@a
+3
+select @b;
+@b
+aaaa
+select @c;
+@c
+6.260
+create table t1 (a int not null auto_increment primary key);
+insert into t1 values ();
+insert into t1 values ();
+insert into t1 values ();
+select * from (t1 as t2 left join t1 as t3 using (a)), t1;
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1, (t1 as t2 left join t1 as t3 using (a));
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1;
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a));
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
+a a
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a );
+a
+1
+2
+3
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1;
+a a
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+1 NULL
+select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a );
+a
+1
+2
+3
+select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a
+1
+2
+3
+select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a));
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
+a a
+1 2
+1 3
+2 2
+2 3
+3 2
+3 3
+NULL 1
+select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+2 2
+2 3
+3 1
+3 2
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a );
+a
+1
+2
+3
+select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1;
+a
+1
+2
+3
+select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a));
+a
+1
+2
+3
+select * from t1 natural join (t1 as t2 left join t1 as t3 using (a));
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1;
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522);
+CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522);
+select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5;
+aa id t2_id id
+2 8299 2517 2517
+3 8301 2518 2518
+4 8302 2519 2519
+5 8303 2520 2520
+6 8304 2521 2521
+drop table t1,t2;
+create table t1 (id1 int NOT NULL);
+create table t2 (id2 int NOT NULL);
+create table t3 (id3 int NOT NULL);
+create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4));
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t2 values (1);
+insert into t4 values (1,1);
+explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t4 const id4 NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+id1 id2 id3 id4 id44
+1 1 NULL NULL NULL
+drop table t1,t2,t3,t4;
+create table t1(s varchar(10) not null);
+create table t2(s varchar(10) not null primary key);
+create table t3(s varchar(10) not null primary key);
+insert into t1 values ('one\t'), ('two\t');
+insert into t2 values ('one\r'), ('two\t');
+insert into t3 values ('one '), ('two\t');
+select * from t1 where s = 'one';
+s
+select * from t2 where s = 'one';
+s
+select * from t3 where s = 'one';
+s
+one
+select * from t1,t2 where t1.s = t2.s;
+s s
+two two
+select * from t2,t3 where t2.s = t3.s;
+s s
+two two
+drop table t1, t2, t3;
+create table t1 (a integer, b integer, index(a), index(b));
+create table t2 (c integer, d integer, index(c), index(d));
+insert into t1 values (1,2), (2,2), (3,2), (4,2);
+insert into t2 values (1,3), (2,3), (3,4), (4,4);
+explain select * from t1 left join t2 on a=c where d in (4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref c,d d 5 const 2
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+select * from t1 left join t2 on a=c where d in (4);
+a b c d
+3 2 3 4
+4 2 4 4
+explain select * from t1 left join t2 on a=c where d = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref c,d d 5 const 2
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+select * from t1 left join t2 on a=c where d = 4;
+a b c d
+3 2 3 4
+4 2 4 4
+drop table t1, t2;
+CREATE TABLE t1 (
+i int(11) NOT NULL default '0',
+c char(10) NOT NULL default '',
+PRIMARY KEY (i),
+UNIQUE KEY c (c)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'a');
+INSERT INTO t1 VALUES (2,'b');
+INSERT INTO t1 VALUES (3,'c');
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+DROP TABLE t1;
+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');
+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
+1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE 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
+1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where
+DROP TABLE t1, t2;
+CREATE TABLE t1 ( city char(30) );
+INSERT INTO t1 VALUES ('London');
+INSERT INTO t1 VALUES ('Paris');
+SELECT * FROM t1 WHERE city='London';
+city
+London
+SELECT * FROM t1 WHERE city='london';
+city
+London
+EXPLAIN SELECT * FROM t1 WHERE city='London' AND city='london';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE city='London' AND city='london';
+city
+London
+EXPLAIN SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London';
+city
+London
+DROP TABLE t1;
+create table t1 (a int(11) unsigned, b int(11) unsigned);
+insert into t1 values (1,0), (1,1), (1,2);
+select a-b from t1 order by 1;
+a-b
+0
+1
+18446744073709551615
+select a-b , (a-b < 0) from t1 order by 1;
+a-b (a-b < 0)
+0 0
+1 0
+18446744073709551615 0
+select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0;
+d (a-b >= 0) b
+1 1 0
+0 1 1
+18446744073709551615 1 2
+select cast((a - b) as unsigned) from t1 order by 1;
+cast((a - b) as unsigned)
+0
+1
+18446744073709551615
+drop table t1;
+create table t1 (a int(11));
+select all all * from t1;
+a
+select distinct distinct * from t1;
+a
+select all distinct * from t1;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+select distinct all * from t1;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+drop table t1;
+CREATE TABLE t1 (
+kunde_intern_id int(10) unsigned NOT NULL default '0',
+kunde_id int(10) unsigned NOT NULL default '0',
+FK_firma_id int(10) unsigned NOT NULL default '0',
+aktuell enum('Ja','Nein') NOT NULL default 'Ja',
+vorname varchar(128) NOT NULL default '',
+nachname varchar(128) NOT NULL default '',
+geloescht enum('Ja','Nein') NOT NULL default 'Nein',
+firma varchar(128) NOT NULL default ''
+);
+INSERT INTO t1 VALUES
+(3964,3051,1,'Ja','Vorname1','1Nachname','Nein','Print Schau XXXX'),
+(3965,3051111,1,'Ja','Vorname1111','1111Nachname','Nein','Print Schau XXXX');
+SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, geloescht FROM t1
+WHERE
+(
+(
+( '' != '' AND firma LIKE CONCAT('%', '', '%'))
+OR
+(vorname LIKE CONCAT('%', 'Vorname1', '%') AND
+nachname LIKE CONCAT('%', '1Nachname', '%') AND
+'Vorname1' != '' AND 'xxxx' != '')
+)
+AND
+(
+aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2
+)
+)
+;
+kunde_id FK_firma_id aktuell vorname nachname geloescht
+SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname,
+geloescht FROM t1
+WHERE
+(
+(
+aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2
+)
+AND
+(
+( '' != '' AND firma LIKE CONCAT('%', '', '%') )
+OR
+( vorname LIKE CONCAT('%', 'Vorname1', '%') AND
+nachname LIKE CONCAT('%', '1Nachname', '%') AND 'Vorname1' != '' AND
+'xxxx' != '')
+)
+)
+;
+kunde_id FK_firma_id aktuell vorname nachname geloescht
+SELECT COUNT(*) FROM t1 WHERE
+( 0 OR (vorname LIKE '%Vorname1%' AND nachname LIKE '%1Nachname%' AND 1))
+AND FK_firma_id = 2;
+COUNT(*)
+0
+drop table t1;
+CREATE TABLE t1 (b BIGINT(20) UNSIGNED NOT NULL, PRIMARY KEY (b));
+INSERT INTO t1 VALUES (0x8000000000000000);
+SELECT b FROM t1 WHERE b=0x8000000000000000;
+b
+9223372036854775808
+DROP TABLE t1;
+CREATE TABLE `t1` ( `gid` int(11) default NULL, `uid` int(11) default NULL);
+CREATE TABLE `t2` ( `ident` int(11) default NULL, `level` char(16) default NULL);
+INSERT INTO `t2` VALUES (0,'READ');
+CREATE TABLE `t3` ( `id` int(11) default NULL, `name` char(16) default NULL);
+INSERT INTO `t3` VALUES (1,'fs');
+select * from t3 left join t1 on t3.id = t1.uid, t2 where t2.ident in (0, t1.gid, t3.id, 0);
+id name gid uid ident level
+1 fs NULL NULL 0 READ
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+acct_id int(11) NOT NULL default '0',
+profile_id smallint(6) default NULL,
+UNIQUE KEY t1$acct_id (acct_id),
+KEY t1$profile_id (profile_id)
+);
+INSERT INTO t1 VALUES (132,17),(133,18);
+CREATE TABLE t2 (
+profile_id smallint(6) default NULL,
+queue_id int(11) default NULL,
+seq int(11) default NULL,
+KEY t2$queue_id (queue_id)
+);
+INSERT INTO t2 VALUES (17,31,4),(17,30,3),(17,36,2),(17,37,1);
+CREATE TABLE t3 (
+id int(11) NOT NULL default '0',
+qtype int(11) default NULL,
+seq int(11) default NULL,
+warn_lvl int(11) default NULL,
+crit_lvl int(11) default NULL,
+rr1 tinyint(4) NOT NULL default '0',
+rr2 int(11) default NULL,
+default_queue tinyint(4) NOT NULL default '0',
+KEY t3$qtype (qtype),
+KEY t3$id (id)
+);
+INSERT INTO t3 VALUES (30,1,29,NULL,NULL,0,NULL,0),(31,1,28,NULL,NULL,0,NULL,0),
+(36,1,34,NULL,NULL,0,NULL,0),(37,1,35,NULL,NULL,0,121,0);
+SELECT COUNT(*) FROM t1 a STRAIGHT_JOIN t2 pq STRAIGHT_JOIN t3 q
+WHERE
+(pq.profile_id = a.profile_id) AND (a.acct_id = 132) AND
+(pq.queue_id = q.id) AND (q.rr1 <> 1);
+COUNT(*)
+4
+drop table t1,t2,t3;
+create table t1 (f1 int);
+insert into t1 values (1),(NULL);
+create table t2 (f2 int, f3 int, f4 int);
+create index idx1 on t2 (f4);
+insert into t2 values (1,2,3),(2,4,6);
+select A.f2 from t1 left join t2 A on A.f2 = f1 where A.f3=(select min(f3)
+from t2 C where A.f4 = C.f4) or A.f3 IS NULL;
+f2
+1
+NULL
+drop table t1,t2;
+create table t2 (a tinyint unsigned);
+create index t2i on t2(a);
+insert into t2 values (0), (254), (255);
+explain select * from t2 where a > -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index t2i t2i 2 NULL 3 Using where; Using index
+select * from t2 where a > -1;
+a
+0
+254
+255
+drop table t2;
+CREATE TABLE t1 (a int, b int, c int);
+INSERT INTO t1
+SELECT 50, 3, 3 FROM DUAL
+WHERE NOT EXISTS
+(SELECT * FROM t1 WHERE a = 50 AND b = 3);
+SELECT * FROM t1;
+a b c
+50 3 3
+INSERT INTO t1
+SELECT 50, 3, 3 FROM DUAL
+WHERE NOT EXISTS
+(SELECT * FROM t1 WHERE a = 50 AND b = 3);
+select found_rows();
+found_rows()
+0
+SELECT * FROM t1;
+a b c
+50 3 3
+select count(*) from t1;
+count(*)
+1
+select found_rows();
+found_rows()
+1
+select count(*) from t1 limit 2,3;
+count(*)
+select found_rows();
+found_rows()
+0
+select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3;
+count(*)
+select found_rows();
+found_rows()
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+(SELECT a, b AS c FROM t1) ORDER BY c+1;
+a c
+(SELECT a, b AS c FROM t1) ORDER BY b+1;
+a c
+SELECT a, b AS c FROM t1 ORDER BY c+1;
+a c
+SELECT a, b AS c FROM t1 ORDER BY b+1;
+a c
+drop table t1;
+create table t1(f1 int, f2 int);
+create table t2(f3 int);
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1));
+f1
+select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1));
+f1
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL));
+f1
+insert into t1 values(1,1),(2,null);
+insert into t2 values(2);
+select * from t1,t2 where f1=f3 and (f1,f2) = (2,null);
+f1 f2 f3
+select * from t1,t2 where f1=f3 and (f1,f2) <=> (2,null);
+f1 f2 f3
+2 NULL 2
+drop table t1,t2;
+create table t1 (f1 int not null auto_increment primary key, f2 varchar(10));
+create table t11 like t1;
+insert into t1 values(1,""),(2,"");
+show table status like 't1%';
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL
+t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL
+select 123 as a from t1 where f1 is null;
+a
+drop table t1,t11;
+CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL, UNIQUE idx (a,b) );
+INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4);
+CREATE TABLE t2 ( a INT NOT NULL, b INT NOT NULL, e INT );
+INSERT INTO t2 VALUES ( 1,10,1), (1,10,2), (1,11,1), (1,11,2), (1,2,1), (1,2,2),(1,2,3);
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN
+t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c;
+a b c d
+1 2 1 1
+1 2 2 1
+1 2 3 1
+1 10 2
+1 11 2
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN
+t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY t1.a, t1.b, c;
+a b c d
+1 10 4
+1 2 1 1
+1 2 2 1
+1 2 3 1
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN
+t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY t2.a, t2.b, c;
+a b c d
+1 2 1 1
+1 2 2 1
+1 2 3 1
+1 10 2
+1 11 2
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2,t1
+WHERE t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c;
+a b c d
+1 2 1 1
+1 2 2 1
+1 2 3 1
+DROP TABLE IF EXISTS t1, t2;
+create table t1 (f1 int primary key, f2 int);
+create table t2 (f3 int, f4 int, primary key(f3,f4));
+insert into t1 values (1,1);
+insert into t2 values (1,1),(1,2);
+select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1;
+count(f2) >0
+1
+drop table t1,t2;
+create table t1 (f1 int,f2 int);
+insert into t1 values(1,1);
+create table t2 (f3 int, f4 int, primary key(f3,f4));
+insert into t2 values(1,1);
+select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2));
+f1 f2
+1 1
+drop table t1,t2;
+CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c));
+insert into t1 values (1,0,0),(2,0,0);
+CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a));
+insert into t2 values (1,'',''), (2,'','');
+CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b));
+insert into t3 values (1,1),(1,2);
+explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
+where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
+t2.b like '%%' order by t2.b limit 0,1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
+1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int, INDEX idx(a));
+INSERT INTO t1 VALUES (2), (3), (1);
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (idx);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (a);
+ERROR 42000: Key 'a' doesn't exist in table 't1'
+EXPLAIN SELECT * FROM t1 FORCE INDEX (a);
+ERROR 42000: Key 'a' doesn't exist in table 't1'
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,1), (2,1), (4,10);
+CREATE TABLE t2 (a int PRIMARY KEY, b int, KEY b (b));
+INSERT INTO t2 VALUES (1,NULL), (2,10);
+ALTER TABLE t1 ENABLE KEYS;
+EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index b b 5 NULL 2 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+a b a b
+1 NULL 1 1
+1 NULL 2 1
+1 NULL 4 10
+2 10 4 10
+EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index b b 5 NULL 2 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+a b a b
+1 NULL 1 1
+1 NULL 2 1
+1 NULL 4 10
+2 10 4 10
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (key1 float default NULL, UNIQUE KEY key1 (key1));
+CREATE TABLE t2 (key2 float default NULL, UNIQUE KEY key2 (key2));
+INSERT INTO t1 VALUES (0.3762),(0.3845),(0.6158),(0.7941);
+INSERT INTO t2 VALUES (1.3762),(1.3845),(1.6158),(1.7941);
+explain select max(key1) from t1 where key1 <= 0.6158;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select max(key2) from t2 where key2 <= 1.6158;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select min(key1) from t1 where key1 >= 0.3762;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select min(key2) from t2 where key2 >= 1.3762;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select max(key1), min(key2) from t1, t2
+where key1 <= 0.6158 and key2 >= 1.3762;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+select max(key1) from t1 where key1 <= 0.6158;
+max(key1)
+0.615800023078918
+select max(key2) from t2 where key2 <= 1.6158;
+max(key2)
+1.61580002307892
+select min(key1) from t1 where key1 >= 0.3762;
+min(key1)
+0.376199990510941
+select min(key2) from t2 where key2 >= 1.3762;
+min(key2)
+1.37619996070862
+select max(key1), min(key2) from t1, t2
+where key1 <= 0.6158 and key2 >= 1.3762;
+max(key1) min(key2)
+0.615800023078918 1.37619996070862
+select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+max(key1)
+0.615800023078918
+select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+min(key1)
+0.376199990510941
+DROP TABLE t1,t2;
+CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
+INSERT INTO t1 VALUES (10);
+SELECT i='1e+01',i=1e+01, i in (1e+01,1e+01), i in ('1e+01','1e+01') FROM t1;
+i='1e+01' i=1e+01 i in (1e+01,1e+01) i in ('1e+01','1e+01')
+1 1 1 1
+DROP TABLE t1;
+create table t1(a bigint unsigned, b bigint);
+insert into t1 values (0xfffffffffffffffff, 0xfffffffffffffffff),
+(0x10000000000000000, 0x10000000000000000),
+(0x8fffffffffffffff, 0x8fffffffffffffff);
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 1
+Warning 1264 Out of range value for column 'b' at row 1
+Warning 1264 Out of range value for column 'a' at row 2
+Warning 1264 Out of range value for column 'b' at row 2
+Warning 1264 Out of range value for column 'b' at row 3
+select hex(a), hex(b) from t1;
+hex(a) hex(b)
+FFFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF
+8FFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF
+drop table t1;
+CREATE TABLE t1 (c0 int);
+CREATE TABLE t2 (c0 int);
+INSERT INTO t1 VALUES(@@connect_timeout);
+INSERT INTO t2 VALUES(@@connect_timeout);
+SELECT * FROM t1 JOIN t2 ON t1.c0 = t2.c0 WHERE (t1.c0 <=> @@connect_timeout);
+c0 c0
+X X
+DROP TABLE t1, t2;
+End of 4.1 tests
+CREATE TABLE t1 (
+K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '',
+K4N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000',
+F2I4 int(11) NOT NULL default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES
+('W%RT', '0100', 1),
+('W-RT', '0100', 1),
+('WART', '0100', 1),
+('WART', '0200', 1),
+('WERT', '0100', 2),
+('WORT','0200', 2),
+('WT', '0100', 2),
+('W_RT', '0100', 2),
+('WaRT', '0100', 3),
+('WART', '0300', 3),
+('WRT' , '0400', 3),
+('WURM', '0500', 3),
+('W%T', '0600', 4),
+('WA%T', '0700', 4),
+('WA_T', '0800', 4);
+SELECT K2C4, K4N4, F2I4 FROM t1
+WHERE K2C4 = 'WART' AND
+(F2I4 = 2 AND K2C4 = 'WART' OR (F2I4 = 2 OR K4N4 = '0200'));
+K2C4 K4N4 F2I4
+WART 0200 1
+SELECT K2C4, K4N4, F2I4 FROM t1
+WHERE K2C4 = 'WART' AND (K2C4 = 'WART' OR K4N4 = '0200');
+K2C4 K4N4 F2I4
+WART 0100 1
+WART 0200 1
+WART 0300 3
+DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 like t1;
+select t1.a from (t1 inner join t2 on t1.a=t2.a) where t2.a=1;
+a
+select t1.a from ((t1 inner join t2 on t1.a=t2.a)) where t2.a=1;
+a
+select x.a, y.a, z.a from ( (t1 x inner join t2 y on x.a=y.a) inner join t2 z on y.a=z.a) WHERE x.a=1;
+a a a
+drop table t1,t2;
+create table t1 (s1 varchar(5));
+insert into t1 values ('Wall');
+select min(s1) from t1 group by s1 with rollup;
+min(s1)
+Wall
+Wall
+drop table t1;
+create table t1 (s1 int) engine=myisam;
+insert into t1 values (0);
+select avg(distinct s1) from t1 group by s1 with rollup;
+avg(distinct s1)
+0.0000
+0.0000
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (null),(1);
+select distinct avg(s1) as x from t1 group by s1 with rollup;
+x
+NULL
+1.0000
+drop table t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+INSERT INTO t2 VALUES (2), (4), (6);
+SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
+a
+2
+4
+EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 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
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON 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 3
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+DROP TABLE t1,t2;
+select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
+x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
+16 16 2 2
+create table t1 (f1 varchar(6) default NULL, f2 int(6) primary key not null);
+create table t2 (f3 varchar(5) not null, f4 varchar(5) not null, UNIQUE KEY UKEY (f3,f4));
+insert into t1 values (" 2", 2);
+insert into t2 values (" 2", " one "),(" 2", " two ");
+select * from t1 left join t2 on f1 = f3;
+f1 f2 f3 f4
+ 2 2 2 one
+ 2 2 2 two
+drop table t1,t2;
+create table t1 (empnum smallint, grp int);
+create table t2 (empnum int, name char(5));
+insert into t1 values(1,1);
+insert into t2 values(1,'bob');
+create view v1 as select * from t2 inner join t1 using (empnum);
+select * from v1;
+empnum name grp
+1 bob 1
+drop table t1,t2;
+drop view v1;
+create table t1 (pk int primary key, b int);
+create table t2 (pk int primary key, c int);
+select pk from t1 inner join t2 using (pk);
+pk
+drop table t1,t2;
+create table t1 (s1 int, s2 char(5), s3 decimal(10));
+create view v1 as select s1, s2, 'x' as s3 from t1;
+select * from t1 natural join v1;
+s1 s2 s3
+insert into t1 values (1,'x',5);
+select * from t1 natural join v1;
+s1 s2 s3
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'x'
+drop table t1;
+drop view v1;
+create table t1(a1 int);
+create table t2(a2 int);
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create view v2 (c) as select a1 from t1;
+select * from t1 natural left join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from t1 natural right join t2;
+a2 a1
+1 1
+2 1
+1 2
+2 2
+select * from v2 natural left join t2;
+c a2
+1 1
+2 1
+1 2
+2 2
+select * from v2 natural right join t2;
+a2 c
+1 1
+2 1
+1 2
+2 2
+drop table t1, t2;
+drop view v2;
+create table t1 (a int(10), t1_val int(10));
+create table t2 (b int(10), t2_val int(10));
+create table t3 (a int(10), b int(10));
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(2,2),(3,3);
+insert into t3 values (1,1),(2,1),(3,1),(4,1);
+select * from t1 natural join t2 natural join t3;
+a b t1_val t2_val
+1 1 1 1
+2 1 2 1
+select * from t1 natural join t3 natural join t2;
+b a t1_val t2_val
+1 1 1 1
+1 2 2 1
+drop table t1, t2, t3;
+DO IFNULL(NULL, NULL);
+SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL);
+CAST(IFNULL(NULL, NULL) AS DECIMAL)
+NULL
+SELECT ABS(IFNULL(NULL, NULL));
+ABS(IFNULL(NULL, NULL))
+NULL
+SELECT IFNULL(NULL, NULL);
+IFNULL(NULL, NULL)
+NULL
+SET @OLD_SQL_MODE12595=@@SQL_MODE, @@SQL_MODE='';
+SHOW LOCAL VARIABLES LIKE 'SQL_MODE';
+Variable_name Value
+sql_mode
+CREATE TABLE BUG_12595(a varchar(100));
+INSERT INTO BUG_12595 VALUES ('hakan%'), ('hakank'), ("ha%an");
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%';
+a
+hakan%
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*';
+a
+hakan%
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan%' ESCAPE '';
+a
+hakan%
+hakank
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%' ESCAPE '';
+a
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE 0x5c;
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha%%an' ESCAPE '%';
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE '\\';
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha|%an' ESCAPE '|';
+a
+ha%an
+SET @@SQL_MODE='NO_BACKSLASH_ESCAPES';
+SHOW LOCAL VARIABLES LIKE 'SQL_MODE';
+Variable_name Value
+sql_mode NO_BACKSLASH_ESCAPES
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%';
+a
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*';
+a
+hakan%
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%' ESCAPE '\\';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan%' ESCAPE '';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE 0x5c;
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha|%an' ESCAPE '|';
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\n%' ESCAPE '\n';
+ERROR HY000: Incorrect arguments to ESCAPE
+SET @@SQL_MODE=@OLD_SQL_MODE12595;
+DROP TABLE BUG_12595;
+create table t1 (a char(1));
+create table t2 (a char(1));
+insert into t1 values ('a'),('b'),('c');
+insert into t2 values ('b'),('c'),('d');
+select a from t1 natural join t2;
+a
+b
+c
+select * from t1 natural join t2 where a = 'b';
+a
+b
+drop table t1, t2;
+CREATE TABLE t1 (`id` TINYINT);
+CREATE TABLE t2 (`id` TINYINT);
+CREATE TABLE t3 (`id` TINYINT);
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+SELECT t1.id,t3.id FROM t1 JOIN t2 ON (t2.id=t1.id) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+SELECT t1.id,t3.id FROM t1 JOIN t2 ON (t2.notacolumn=t1.id) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+SELECT id,t3.id FROM t1 JOIN t2 ON (t2.id=t1.id) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+SELECT id,t3.id FROM (t1 JOIN t2 ON (t2.id=t1.id)) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+drop table t1, t2, t3;
+create table t1 (a int(10),b int(10));
+create table t2 (a int(10),b int(10));
+insert into t1 values (1,10),(2,20),(3,30);
+insert into t2 values (1,10);
+select * from t1 inner join t2 using (A);
+a b b
+1 10 10
+select * from t1 inner join t2 using (a);
+a b b
+1 10 10
+drop table t1, t2;
+create table t1 (a int, c int);
+create table t2 (b int);
+create table t3 (b int, a int);
+create table t4 (c int);
+insert into t1 values (1,1);
+insert into t2 values (1);
+insert into t3 values (1,1);
+insert into t4 values (1);
+select * from t1 join t2 join t3 on (t2.b = t3.b and t1.a = t3.a);
+a c b b a
+1 1 1 1 1
+select * from t1, t2 join t3 on (t2.b = t3.b and t1.a = t3.a);
+ERROR 42S22: Unknown column 't1.a' in 'on clause'
+select * from t1 join t2 join t3 join t4 on (t1.a = t4.c and t2.b = t4.c);
+a c b b a c
+1 1 1 1 1 1
+select * from t1 join t2 join t4 using (c);
+c a b
+1 1 1
+drop table t1, t2, t3, t4;
+create table t1(x int, y int);
+create table t2(x int, y int);
+create table t3(x int, primary key(x));
+insert into t1 values (1, 1), (2, 1), (3, 1), (4, 3), (5, 6), (6, 6);
+insert into t2 values (1, 1), (2, 1), (3, 3), (4, 6), (5, 6);
+insert into t3 values (1), (2), (3), (4), (5);
+select t1.x, t3.x from t1, t2, t3 where t1.x = t2.x and t3.x >= t1.y and t3.x <= t2.y;
+x x
+1 1
+2 1
+3 1
+3 2
+3 3
+4 3
+4 4
+4 5
+drop table t1,t2,t3;
+create table t1 (id char(16) not null default '', primary key (id));
+insert into t1 values ('100'),('101'),('102');
+create table t2 (id char(16) default null);
+insert into t2 values (1);
+create view v1 as select t1.id from t1;
+create view v2 as select t2.id from t2;
+create view v3 as select (t1.id+2) as id from t1 natural left join t2;
+select t1.id from t1 left join v2 using (id);
+id
+100
+101
+102
+select t1.id from v2 right join t1 using (id);
+id
+100
+101
+102
+select t1.id from t1 left join v3 using (id);
+id
+102
+100
+101
+select * from t1 left join v2 using (id);
+id
+100
+101
+102
+select * from v2 right join t1 using (id);
+id
+100
+101
+102
+select * from t1 left join v3 using (id);
+id
+102
+100
+101
+select v1.id from v1 left join v2 using (id);
+id
+100
+101
+102
+select v1.id from v2 right join v1 using (id);
+id
+100
+101
+102
+select v1.id from v1 left join v3 using (id);
+id
+102
+100
+101
+select * from v1 left join v2 using (id);
+id
+100
+101
+102
+select * from v2 right join v1 using (id);
+id
+100
+101
+102
+select * from v1 left join v3 using (id);
+id
+102
+100
+101
+drop table t1, t2;
+drop view v1, v2, v3;
+create table t1 (id int(11) not null default '0');
+insert into t1 values (123),(191),(192);
+create table t2 (id char(16) character set utf8 not null);
+insert into t2 values ('58013'),('58014'),('58015'),('58016');
+create table t3 (a_id int(11) not null, b_id char(16) character set utf8);
+insert into t3 values (123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013');
+select count(*)
+from t1 inner join (t3 left join t2 on t2.id = t3.b_id) on t1.id = t3.a_id;
+count(*)
+6
+select count(*)
+from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id;
+count(*)
+6
+drop table t1,t2,t3;
+create table t1 (a int);
+create table t2 (b int);
+create table t3 (c int);
+select * from t1 join t2 join t3 on (t1.a=t3.c);
+a b c
+select * from t1 join t2 left join t3 on (t1.a=t3.c);
+a b c
+select * from t1 join t2 right join t3 on (t1.a=t3.c);
+a b c
+select * from t1 join t2 straight_join t3 on (t1.a=t3.c);
+a b c
+drop table t1, t2 ,t3;
+create table t1(f1 int, f2 date);
+insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'),
+(4,'2005-10-01'),(5,'2005-12-30');
+select * from t1 where f2 >= 0 order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+3 2005-09-30
+4 2005-10-01
+5 2005-12-30
+select * from t1 where f2 >= '0000-00-00' order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+3 2005-09-30
+4 2005-10-01
+5 2005-12-30
+select * from t1 where f2 >= '2005-09-31' order by f2;
+f1 f2
+4 2005-10-01
+5 2005-12-30
+select * from t1 where f2 >= '2005-09-3a' order by f2;
+f1 f2
+3 2005-09-30
+4 2005-10-01
+5 2005-12-30
+Warnings:
+Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+select * from t1 where f2 <= '2005-09-31' order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+3 2005-09-30
+select * from t1 where f2 <= '2005-09-3a' order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+Warnings:
+Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+drop table t1;
+create table t1 (f1 int, f2 int);
+insert into t1 values (1, 30), (2, 20), (3, 10);
+create algorithm=merge view v1 as select f1, f2 from t1;
+create algorithm=merge view v2 (f2, f1) as select f1, f2 from t1;
+create algorithm=merge view v3 as select t1.f1 as f2, t1.f2 as f1 from t1;
+select t1.f1 as x1, f1 from t1 order by t1.f1;
+x1 f1
+1 1
+2 2
+3 3
+select v1.f1 as x1, f1 from v1 order by v1.f1;
+x1 f1
+1 1
+2 2
+3 3
+select v2.f1 as x1, f1 from v2 order by v2.f1;
+x1 f1
+10 10
+20 20
+30 30
+select v3.f1 as x1, f1 from v3 order by v3.f1;
+x1 f1
+10 10
+20 20
+30 30
+select f1, f2, v1.f1 as x1 from v1 order by v1.f1;
+f1 f2 x1
+1 30 1
+2 20 2
+3 10 3
+select f1, f2, v2.f1 as x1 from v2 order by v2.f1;
+f1 f2 x1
+10 3 10
+20 2 20
+30 1 30
+select f1, f2, v3.f1 as x1 from v3 order by v3.f1;
+f1 f2 x1
+10 3 10
+20 2 20
+30 1 30
+drop table t1;
+drop view v1, v2, v3;
+CREATE TABLE t1(key_a int4 NOT NULL, optimus varchar(32), PRIMARY KEY(key_a));
+CREATE TABLE t2(key_a int4 NOT NULL, prime varchar(32), PRIMARY KEY(key_a));
+CREATE table t3(key_a int4 NOT NULL, key_b int4 NOT NULL, foo varchar(32),
+PRIMARY KEY(key_a,key_b));
+INSERT INTO t1 VALUES (0,'');
+INSERT INTO t1 VALUES (1,'i');
+INSERT INTO t1 VALUES (2,'j');
+INSERT INTO t1 VALUES (3,'k');
+INSERT INTO t2 VALUES (1,'r');
+INSERT INTO t2 VALUES (2,'s');
+INSERT INTO t2 VALUES (3,'t');
+INSERT INTO t3 VALUES (1,5,'x');
+INSERT INTO t3 VALUES (1,6,'y');
+INSERT INTO t3 VALUES (2,5,'xx');
+INSERT INTO t3 VALUES (2,6,'yy');
+INSERT INTO t3 VALUES (2,7,'zz');
+INSERT INTO t3 VALUES (3,5,'xxx');
+SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+key_a foo
+2 xx
+EXPLAIN SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1
+SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+key_a foo
+2 xx
+EXPLAIN SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1
+DROP TABLE t1,t2,t3;
+create table t1 (f1 int);
+insert into t1 values(1),(2);
+create table t2 (f2 int, f3 int, key(f2));
+insert into t2 values(1,1),(2,2);
+create table t3 (f4 int not null);
+insert into t3 values (2),(2),(2);
+select f1,(select count(*) from t2,t3 where f2=f1 and f3=f4) as count from t1;
+f1 count
+1 0
+2 3
+drop table t1,t2,t3;
+create table t1 (f1 int unique);
+create table t2 (f2 int unique);
+create table t3 (f3 int unique);
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+insert into t3 values(1),(NULL);
+select * from t3 where f3 is null;
+f3
+NULL
+select t2.f2 from t1 left join t2 on f1=f2 join t3 on f1=f3 where f1=1;
+f2
+1
+drop table t1,t2,t3;
+create table t1(f1 char, f2 char not null);
+insert into t1 values(null,'a');
+create table t2 (f2 char not null);
+insert into t2 values('b');
+select * from t1 left join t2 on f1=t2.f2 where t1.f2='a';
+f1 f2 f2
+NULL a NULL
+drop table t1,t2;
+select * from (select * left join t on f1=f2) tt;
+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 'on f1=f2) tt' at line 1
+CREATE TABLE t1 (sku int PRIMARY KEY, pr int);
+CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255));
+INSERT INTO t1 VALUES
+(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
+INSERT INTO t2 VALUES
+(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
+(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
+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);
+sku sppr name sku pr
+20 10 bbb 10 10
+20 10 bbb 20 10
+EXPLAIN
+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; Using MRR
+DROP TABLE t1,t2;
+CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
+INSERT t1 SET i = 0;
+UPDATE t1 SET i = -1;
+Warnings:
+Warning 1264 Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+0
+UPDATE t1 SET i = CAST(i - 1 AS SIGNED);
+Warnings:
+Warning 1264 Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+0
+UPDATE t1 SET i = i - 1;
+Warnings:
+Warning 1264 Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+255
+DROP TABLE t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, c int, e int, primary key(a,b,c));
+insert into t2 select A.a, B.a, C.a, C.a from t1 A, t1 B, t1 C;
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+select 'In next EXPLAIN, B.rows must be exactly 10:' Z;
+Z
+In next EXPLAIN, B.rows must be exactly 10:
+explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
+and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using index condition; Using where; Using MRR
+1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10 Using join buffer (flat, BKA join)
+drop table t1, t2;
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
+INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2),
+(3,1), (5,1), (8,9), (2,2), (0,9);
+CREATE TABLE t2 (c int, d int, f int, INDEX(c,f));
+INSERT INTO t2 VALUES
+(1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1),
+(5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1),
+(0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1);
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using MRR
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join)
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Using MRR
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join)
+DROP TABLE t1, t2;
+create table t1 (
+a int unsigned not null auto_increment primary key,
+b bit not null,
+c bit not null
+);
+create table t2 (
+a int unsigned not null auto_increment primary key,
+b bit not null,
+c int unsigned not null,
+d varchar(50)
+);
+insert into t1 (b,c) values (0,1), (0,1);
+insert into t2 (b,c) values (0,1);
+select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d
+from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1
+where t1.b <> 1 order by t1.a;
+a t1.b + 0 t1.c + 0 a t2.b + 0 c d
+1 0 1 1 0 1 NULL
+2 0 1 NULL NULL NULL NULL
+drop table t1,t2;
+SELECT 0.9888889889 * 1.011111411911;
+0.9888889889 * 1.011111411911
+0.9998769417899202067879
+prepare stmt from 'select 1 as " a "';
+Warnings:
+Warning 1466 Leading spaces are removed from name ' a '
+execute stmt;
+a
+1
+CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+CREATE TABLE t2 (c int NOT NULL, INDEX idx(c));
+INSERT INTO t2 VALUES
+(1), (1), (1), (1), (1), (1), (1), (1),
+(2), (2), (2), (2),
+(3), (3),
+(4);
+EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 ref idx idx 4 const 7 Using index
+EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 ref idx idx 4 const 1 Using index
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2);
+CREATE TABLE t2 (b int, c INT, INDEX idx1(b));
+INSERT INTO t2 VALUES (2,1), (3,2);
+CREATE TABLE t3 (d int, e int, INDEX idx1(d));
+INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50);
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
+WHERE t1.id=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 const idx1 NULL NULL NULL 1
+1 SIMPLE t3 ref idx1 idx1 5 const 3
+SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
+WHERE t1.id=2;
+id a b c d e
+2 NULL NULL NULL 2 10
+2 NULL NULL NULL 2 20
+2 NULL NULL NULL 2 40
+2 NULL NULL NULL 2 50
+DROP TABLE t1,t2,t3;
+create table t1 (c1 varchar(1), c2 int, c3 int, c4 int, c5 int, c6 int,
+c7 int, c8 int, c9 int, fulltext key (`c1`));
+select distinct match (`c1`) against ('z') , c2, c3, c4,c5, c6,c7, c8
+from t1 where c9=1 order by c2, c2;
+match (`c1`) against ('z') c2 c3 c4 c5 c6 c7 c8
+drop table t1;
+CREATE TABLE t1 (pk varchar(10) PRIMARY KEY, fk varchar(16));
+CREATE TABLE t2 (pk varchar(16) PRIMARY KEY, fk varchar(10));
+INSERT INTO t1 VALUES
+('d','dddd'), ('i','iii'), ('a','aa'), ('b','bb'), ('g','gg'),
+('e','eee'), ('c','cccc'), ('h','hhh'), ('j','jjj'), ('f','fff');
+INSERT INTO t2 VALUES
+('jjj', 'j'), ('cc','c'), ('ccc','c'), ('aaa', 'a'), ('jjjj','j'),
+('hhh','h'), ('gg','g'), ('fff','f'), ('ee','e'), ('ffff','f'),
+('bbb','b'), ('ff','f'), ('cccc','c'), ('dddd','d'), ('jj','j'),
+('aaaa','a'), ('bb','b'), ('eeee','e'), ('aa','a'), ('hh','h');
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk < 'c' AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Using MRR
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join)
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join)
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join)
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
+CREATE TABLE t2 (a int, b varchar(20) NOT NULL,
+PRIMARY KEY (a), UNIQUE KEY (b));
+INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
+INSERT INTO t2 VALUES (1,'a'),(2,'b'),(3,'c');
+EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t2.b=t1.b WHERE t1.a=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+DROP TABLE t1,t2;
+CREATE TABLE t1(id int PRIMARY KEY, b int, e int);
+CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a));
+CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c));
+INSERT INTO t1 VALUES
+(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79),
+(6,63,67), (5,55,58), (3,38,39), (8,81,89);
+INSERT INTO t2 VALUES
+(21,210), (41,410), (82,820), (83,830), (84,840),
+(65,650), (51,510), (37,370), (94,940), (76,760),
+(22,220), (33,330), (40,400), (95,950), (38,380),
+(67,670), (88,880), (57,570), (96,960), (97,970);
+INSERT INTO t3 VALUES
+(210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'),
+(440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'),
+(230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'),
+(450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff');
+EXPLAIN
+SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
+WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
+t3.a=t2.a AND t3.c IN ('bb','ee');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Using MRR
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
+EXPLAIN
+SELECT t3.a FROM t1,t2,t3
+WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
+t3.a=t2.a AND t3.c IN ('bb','ee') ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Using MRR
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
+EXPLAIN
+SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
+WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
+t3.c IN ('bb','ee');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Using MRR
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
+EXPLAIN
+SELECT t3.a FROM t1,t2,t3
+WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
+t3.c IN ('bb','ee');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Using MRR
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
+CREATE TABLE t2 ( f11 int PRIMARY KEY );
+INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0);
+INSERT INTO t2 VALUES (62);
+SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1;
+f1 f2 f3 f4 f5 f6 checked_out f11
+1 1 1 0 0 0 0 NULL
+DROP TABLE t1, t2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a int);
+INSERT into t1 values (1), (2), (3);
+SELECT * FROM t1 LIMIT 2, -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 '-1' at line 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+ID_with_null int NULL,
+ID_better int NOT NULL,
+INDEX idx1 (ID_with_null),
+INDEX idx2 (ID_better)
+);
+INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3);
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL;
+COUNT(*)
+128
+SELECT COUNT(*) FROM t1 WHERE ID_better=1;
+COUNT(*)
+2
+EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP INDEX idx1 ON t1;
+CREATE UNIQUE INDEX idx1 ON t1(ID_with_null);
+EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP TABLE t1;
+CREATE TABLE t1 (
+ID1_with_null int NULL,
+ID2_with_null int NULL,
+ID_better int NOT NULL,
+INDEX idx1 (ID1_with_null, ID2_with_null),
+INDEX idx2 (ID_better)
+);
+INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3),
+(3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3);
+INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
+SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3;
+COUNT(*)
+24
+SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL;
+COUNT(*)
+24
+SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL;
+COUNT(*)
+192
+SELECT COUNT(*) FROM t1 WHERE ID_better=1;
+COUNT(*)
+2
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP INDEX idx1 ON t1;
+CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null);
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND
+(ID2_with_null=1 OR ID2_with_null=2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, ts TIMESTAMP, KEY ts(ts));
+INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00");
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+CREATE TABLE t2 (a INT, dt1 DATETIME, dt2 DATETIME, PRIMARY KEY (a));
+INSERT INTO t2 VALUES (30, "2006-01-01 00:00:00", "2999-12-31 00:00:00");
+INSERT INTO t2 SELECT a+1,dt1,dt2 FROM t2;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
+AND t1.ts BETWEEN t2.dt1 AND t2.dt2
+AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where; Using MRR
+Warnings:
+Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
+AND t1.ts BETWEEN t2.dt1 AND t2.dt2
+AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
+a ts a dt1 dt2
+30 2006-01-03 23:00:00 30 2006-01-01 00:00:00 2999-12-31 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
+DROP TABLE t1,t2;
+create table t1 (a bigint unsigned);
+insert into t1 values
+(if(1, 9223372036854775808, 1)),
+(case when 1 then 9223372036854775808 else 1 end),
+(coalesce(9223372036854775808, 1));
+select * from t1;
+a
+9223372036854775808
+9223372036854775808
+9223372036854775808
+drop table t1;
+create table t1 select
+if(1, 9223372036854775808, 1) i,
+case when 1 then 9223372036854775808 else 1 end c,
+coalesce(9223372036854775808, 1) co;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` decimal(19,0) NOT NULL DEFAULT '0',
+ `c` decimal(19,0) NOT NULL DEFAULT '0',
+ `co` decimal(19,0) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+select
+if(1, cast(1111111111111111111 as unsigned), 1) i,
+case when 1 then cast(1111111111111111111 as unsigned) else 1 end c,
+coalesce(cast(1111111111111111111 as unsigned), 1) co;
+i c co
+1111111111111111111 1111111111111111111 1111111111111111111
+CREATE TABLE t1 (name varchar(255));
+CREATE TABLE t2 (name varchar(255), n int, KEY (name(3)));
+INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa');
+INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3);
+INSERT INTO t2 VALUES (concat('cc ', 0x06), 4);
+INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7);
+SELECT * FROM t2;
+name n
+bb 1
+aa 2
+cc 3
+cc  4
+cc 5
+bb 6
+cc 7
+SELECT * FROM t2 ORDER BY name;
+name n
+aa 2
+bb 1
+bb 6
+cc  4
+cc 3
+cc 5
+cc 7
+SELECT name, LENGTH(name), n FROM t2 ORDER BY name;
+name LENGTH(name) n
+aa 2 2
+bb 2 1
+bb 3 6
+cc  4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref name name 6 const 3 Using where
+SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+name LENGTH(name) n
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+name LENGTH(name) n
+cc 5 3
+cc  4 4
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+name LENGTH(name) n
+cc  4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where
+SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+name name n
+ccc NULL NULL
+bb bb 1
+bb bb 6
+cc cc 3
+cc cc 5
+cc cc 7
+aa aa 2
+aa aa 2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (name text);
+CREATE TABLE t2 (name text, n int, KEY (name(3)));
+INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa');
+INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3);
+INSERT INTO t2 VALUES (concat('cc ', 0x06), 4);
+INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7);
+SELECT * FROM t2;
+name n
+bb 1
+aa 2
+cc 3
+cc  4
+cc 5
+bb 6
+cc 7
+SELECT * FROM t2 ORDER BY name;
+name n
+aa 2
+bb 1
+bb 6
+cc  4
+cc 3
+cc 5
+cc 7
+SELECT name, LENGTH(name), n FROM t2 ORDER BY name;
+name LENGTH(name) n
+aa 2 2
+bb 2 1
+bb 3 6
+cc  4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref name name 6 const 3 Using where
+SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+name LENGTH(name) n
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+name LENGTH(name) n
+cc 5 3
+cc  4 4
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+name LENGTH(name) n
+cc  4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where
+SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+name name n
+ccc NULL NULL
+bb bb 1
+bb bb 6
+cc cc 3
+cc cc 5
+cc cc 7
+aa aa 2
+aa aa 2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+access_id int NOT NULL default '0',
+name varchar(20) default NULL,
+rank int NOT NULL default '0',
+KEY idx (access_id)
+);
+CREATE TABLE t2 (
+faq_group_id int NOT NULL default '0',
+faq_id int NOT NULL default '0',
+access_id int default NULL,
+UNIQUE KEY idx1 (faq_id),
+KEY idx2 (faq_group_id,faq_id)
+);
+INSERT INTO t1 VALUES
+(1,'Everyone',2),(2,'Help',3),(3,'Technical Support',1),(4,'Chat User',4);
+INSERT INTO t2 VALUES
+(261,265,1),(490,494,1);
+SELECT t2.faq_id
+FROM t1 INNER JOIN t2 IGNORE INDEX (idx1)
+ON (t1.access_id = t2.access_id)
+LEFT JOIN t2 t
+ON (t.faq_group_id = t2.faq_group_id AND
+find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4'))
+WHERE
+t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265);
+faq_id
+265
+SELECT t2.faq_id
+FROM t1 INNER JOIN t2
+ON (t1.access_id = t2.access_id)
+LEFT JOIN t2 t
+ON (t.faq_group_id = t2.faq_group_id AND
+find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4'))
+WHERE
+t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265);
+faq_id
+265
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, KEY inx (b,a));
+INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7);
+EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
+ON ( f1.b=f2.b AND f1.a<f2.a )
+WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index
+1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT, c2 INT);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2)))))))))))))))))))))))))))))))) > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+31 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+32 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0;
+ERROR HY000: Too high level of nesting for select
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 int(11) NOT NULL AUTO_INCREMENT,
+c2 varchar(1000) DEFAULT NULL,
+c3 bigint(20) DEFAULT NULL,
+c4 bigint(20) DEFAULT NULL,
+PRIMARY KEY (c1)
+);
+EXPLAIN EXTENDED
+SELECT join_2.c1
+FROM
+t1 AS join_0,
+t1 AS join_1,
+t1 AS join_2,
+t1 AS join_3,
+t1 AS join_4,
+t1 AS join_5,
+t1 AS join_6,
+t1 AS join_7
+WHERE
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+OR
+join_0.c2 < '?' AND
+join_1.c2 < '?' AND
+join_2.c2 > '?' AND
+join_2.c2 < '!' AND
+join_3.c2 > '?' AND
+join_4.c2 = '?' AND
+join_5.c2 <> '?' AND
+join_6.c2 <> '?' AND
+join_7.c2 >= '?' AND
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+GROUP BY
+join_3.c1,
+join_2.c1,
+join_7.c1,
+join_1.c1,
+join_0.c1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select NULL AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by NULL,NULL,NULL,NULL,NULL
+SHOW WARNINGS;
+Level Code Message
+Note 1003 select NULL AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by NULL,NULL,NULL,NULL,NULL
+DROP TABLE t1;
+SELECT 1 AS ` `;
+
+1
+Warnings:
+Warning 1474 Name ' ' has become ''
+SELECT 1 AS ` `;
+
+1
+Warnings:
+Warning 1474 Name ' ' has become ''
+SELECT 1 AS ` x`;
+x
+1
+Warnings:
+Warning 1466 Leading spaces are removed from name ' x'
+CREATE VIEW v1 AS SELECT 1 AS ``;
+ERROR 42000: Incorrect column name ''
+CREATE VIEW v1 AS SELECT 1 AS ` `;
+ERROR 42000: Incorrect column name ' '
+CREATE VIEW v1 AS SELECT 1 AS ` `;
+ERROR 42000: Incorrect column name ' '
+CREATE VIEW v1 AS SELECT (SELECT 1 AS ` `);
+ERROR 42000: Incorrect column name ' '
+CREATE VIEW v1 AS SELECT 1 AS ` x`;
+Warnings:
+Warning 1466 Leading spaces are removed from name ' x'
+SELECT `x` FROM v1;
+x
+1
+ALTER VIEW v1 AS SELECT 1 AS ` `;
+ERROR 42000: Incorrect column name ' '
+DROP VIEW v1;
+select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT'
+ and '2007/10/20 00:00:00 GMT';
+str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT'
+ and '2007/10/20 00:00:00 GMT'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT'
+Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT'
+select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007/10/01 00:00:00 GMT-6'
+select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007/10/2000:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007-10-1 00:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007-10-01 x00:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:x00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 x12:34:56 GMT-6'
+select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6';
+str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6'
+select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6';
+str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6'
+select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56';
+str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'
+1
+select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00';
+str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'
+0
+select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00';
+str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'
+1
+select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00';
+str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34'
+select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34';
+str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'
+1
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
+1
+select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
+ and '2007/10/20 00:00:00';
+str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
+ and '2007/10/20 00:00:00'
+1
+set SQL_MODE=TRADITIONAL;
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34'
+select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
+str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34'
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34:00'
+select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01'
+ and '2007/10/20';
+str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01'
+ and '2007/10/20'
+0
+Warnings:
+Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/09/01' at row 1
+Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/10/20' at row 1
+set SQL_MODE=DEFAULT;
+select str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20';
+str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: ''
+select str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20';
+str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20'
+0
+select str_to_date('','%Y-%m-%d %H:%i') = '2007-10-01 12:34';
+str_to_date('','%Y-%m-%d %H:%i') = '2007-10-01 12:34'
+0
+select str_to_date(NULL,'%Y-%m-%d %H:%i') = '2007-10-01 12:34';
+str_to_date(NULL,'%Y-%m-%d %H:%i') = '2007-10-01 12:34'
+NULL
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = ''
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: ''
+select str_to_date('1','%Y-%m-%d') = '1';
+str_to_date('1','%Y-%m-%d') = '1'
+0
+Warnings:
+Warning 1292 Truncated incorrect date value: '1'
+select str_to_date('1','%Y-%m-%d') = '1';
+str_to_date('1','%Y-%m-%d') = '1'
+0
+Warnings:
+Warning 1292 Truncated incorrect date value: '1'
+select str_to_date('','%Y-%m-%d') = '';
+str_to_date('','%Y-%m-%d') = ''
+0
+Warnings:
+Warning 1292 Truncated incorrect date value: ''
+select str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL;
+str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL
+0
+select str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00';
+str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00'
+0
+select str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL;
+str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL
+0
+CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL,
+c22 INT DEFAULT NULL,
+KEY(c21, c22));
+CREATE TABLE t3 (c31 INT UNSIGNED NOT NULL DEFAULT 0,
+c32 INT DEFAULT NULL,
+c33 INT NOT NULL,
+c34 INT UNSIGNED DEFAULT 0,
+KEY (c33, c34, c32));
+INSERT INTO t1 values (),(),(),(),();
+INSERT INTO t2 SELECT a.c11, b.c11 FROM t1 a, t1 b;
+INSERT INTO t3 VALUES (1, 1, 1, 0),
+(2, 2, 0, 0),
+(3, 3, 1, 0),
+(4, 4, 0, 0),
+(5, 5, 1, 0);
+SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
+t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
+t3.c33 = 1 AND t2.c22 in (1, 3)
+ORDER BY c32;
+c32
+1
+1
+3
+3
+5
+5
+SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
+t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
+t3.c33 = 1 AND t2.c22 in (1, 3)
+ORDER BY c32 DESC;
+c32
+5
+5
+3
+3
+1
+1
+DROP TABLE t1, t2, t3;
+
+#
+# Bug#30736: Row Size Too Large Error Creating a Table and
+# Inserting Data.
+#
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+
+CREATE TABLE t1(
+c1 DECIMAL(10, 2),
+c2 FLOAT);
+
+INSERT INTO t1 VALUES (0, 1), (2, 3), (4, 5);
+
+CREATE TABLE t2(
+c3 DECIMAL(10, 2))
+SELECT
+c1 * c2 AS c3
+FROM t1;
+
+SELECT * FROM t1;
+c1 c2
+0.00 1
+2.00 3
+4.00 5
+
+SELECT * FROM t2;
+c3
+0.00
+6.00
+20.00
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+CREATE TABLE t1 (c1 BIGINT NOT NULL);
+INSERT INTO t1 (c1) VALUES (1);
+SELECT * FROM t1 WHERE c1 > NULL + 1;
+c1
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY);
+INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0');
+SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar');
+a
+foo0
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, c INT, KEY(a));
+INSERT INTO t1 VALUES (1, 1), (2, 2);
+INSERT INTO t2 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
+(2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
+(3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
+(4, 1), (4, 2), (4, 3), (4, 4), (4, 5);
+FLUSH STATUS;
+SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3;
+b
+1
+2
+SHOW STATUS LIKE 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 10
+Handler_read_prev 0
+Handler_read_rnd 10
+Handler_read_rnd_next 7
+DROP TABLE t1, t2;
+CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0',
+f2 int(11) NOT NULL default '0',
+f3 bigint(20) NOT NULL default '0',
+f4 varchar(255) NOT NULL default '',
+PRIMARY KEY (f1),
+KEY key1 (f4),
+KEY key2 (f2));
+CREATE TABLE t2 (f1 int(11) NOT NULL default '0',
+f2 enum('A1','A2','A3') NOT NULL default 'A1',
+f3 int(11) NOT NULL default '0',
+PRIMARY KEY (f1),
+KEY key1 (f3));
+CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0',
+f2 datetime NOT NULL default '1980-01-01 00:00:00',
+PRIMARY KEY (f1));
+insert into t1 values (1, 1, 1, 'abc');
+insert into t1 values (2, 1, 2, 'def');
+insert into t1 values (3, 1, 2, 'def');
+insert into t2 values (1, 'A1', 1);
+insert into t3 values (1, '1980-01-01');
+SELECT a.f3, cr.f4, count(*) count
+FROM t2 a
+STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1
+LEFT JOIN
+(t1 cr2
+JOIN t3 ae2 ON cr2.f3 = ae2.f1
+) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND
+cr.f4 = cr2.f4
+GROUP BY a.f3, cr.f4;
+f3 f4 count
+1 abc 1
+1 def 2
+drop table t1, t2, t3;
+CREATE TABLE t1 (a INT KEY, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Using MRR
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Using MRR
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
+DROP TABLE t1;
+#
+# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
+# forcing a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2 Range checked for each record (index map: 0x1)
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+1
+1
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2 Range checked for each record (index map: 0x1)
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+1
+1
+1
+1
+1
+DROP TABLE t1;
+#
+# Bug #48291 : crash with row() operator,select into @var, and
+# subquery returning multiple rows
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (2),(3);
+# Should not crash
+SELECT 1 FROM t1 WHERE a <> 1 AND NOT
+ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
+INTO @var0;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1;
+#
+# Bug #48458: simple query tries to allocate enormous amount of
+# memory
+#
+CREATE TABLE t1(a INT NOT NULL, b YEAR);
+INSERT INTO t1 VALUES ();
+Warnings:
+Warning 1364 Field 'a' doesn't have a default value
+CREATE TABLE t2(c INT);
+# Should not err out because of out-of-memory
+SELECT 1 FROM t2 JOIN t1 ON 1=1
+WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a);
+1
+DROP TABLE t1,t2;
+#
+# Bug #49199: Optimizer handles incorrectly:
+# field='const1' AND field='const2' in some cases
+
+CREATE TABLE t1(a DATETIME NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+a b
+2001-01-01 00:00:00 2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+a b
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 0
+SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+a b
+2001-01-01 00:00:00 2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT x.a, y.a, z.a FROM t1 x
+JOIN t1 y ON x.a=y.a
+JOIN t1 z ON y.a=z.a
+WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+a a a
+2001-01-01 00:00:00 2001-01-01 00:00:00 2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
+JOIN t1 y ON x.a=y.a
+JOIN t1 z ON y.a=z.a
+WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE x system NULL NULL NULL NULL 1 100.00
+1 SIMPLE y system NULL NULL NULL NULL 1 100.00
+1 SIMPLE z system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1
+DROP TABLE t1;
+#
+# Bug #49897: crash in ptr_compare when char(0) NOT NULL
+# column is used for ORDER BY
+#
+SET @old_sort_buffer_size= @@session.sort_buffer_size;
+SET @@sort_buffer_size= 40000;
+CREATE TABLE t1(a CHAR(0) NOT NULL);
+INSERT INTO t1 VALUES (0), (0), (0);
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT a FROM t1 ORDER BY a;
+DROP TABLE t1;
+CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int);
+INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1);
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT a FROM t1 ORDER BY a LIMIT 5;
+a
+
+
+
+
+
+EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+a b c
+ 0
+ 2
+ 1
+ 0
+ 2
+EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
+SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+a b c
+ 0
+ 0
+ 0
+ 0
+ 0
+EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
+SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+a b c
+ 0
+ 0
+ 0
+ 0
+ 0
+SET @@sort_buffer_size= @old_sort_buffer_size;
+DROP TABLE t1;
+End of 5.0 tests
+create table t1(a INT, KEY (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
+SELECT a FROM t1 ORDER BY a LIMIT 2;
+a
+1
+2
+SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296;
+a
+3
+4
+5
+SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297;
+a
+3
+4
+5
+DROP TABLE t1;
+CREATE TABLE A (date_key date);
+CREATE TABLE C (
+pk int,
+int_nokey int,
+int_key int,
+date_key date NOT NULL,
+date_nokey date,
+varchar_key varchar(1)
+);
+INSERT INTO C VALUES
+(1,1,1,'0000-00-00',NULL,NULL),
+(1,1,1,'0000-00-00',NULL,NULL);
+SELECT 1 FROM C WHERE pk > ANY (SELECT 1 FROM C);
+1
+SELECT COUNT(DISTINCT 1) FROM C
+WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
+COUNT(DISTINCT 1)
+SELECT date_nokey FROM C
+WHERE int_key IN (SELECT 1 FROM A)
+HAVING date_nokey = '10:41:7'
+ORDER BY date_key;
+date_nokey
+Warnings:
+Warning 1292 Incorrect date value: '10:41:7' for column 'date_nokey' at row 1
+DROP TABLE A,C;
+CREATE TABLE t1 (a INT NOT NULL, b INT);
+INSERT INTO t1 VALUES (1, 1);
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a) OR b > 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '1' AS `a`,'1' AS `b` from `test`.`t1` where 1
+SELECT * FROM t1 WHERE (a=a AND a=a) OR b > 2;
+a b
+1 1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL);
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
+DROP TABLE t1;
+#
+# Bug#45266: Uninitialized variable lead to an empty result.
+#
+drop table if exists A,AA,B,BB;
+CREATE TABLE `A` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`date_key` date NOT NULL,
+`date_nokey` date NOT NULL,
+`datetime_key` datetime NOT NULL,
+`int_nokey` int(11) NOT NULL,
+`time_key` time NOT NULL,
+`time_nokey` time NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `date_key` (`date_key`),
+KEY `time_key` (`time_key`),
+KEY `datetime_key` (`datetime_key`)
+);
+CREATE TABLE `AA` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`time_key` time NOT NULL,
+KEY `time_key` (`time_key`),
+PRIMARY KEY (`pk`)
+);
+CREATE TABLE `B` (
+`date_nokey` date NOT NULL,
+`date_key` date NOT NULL,
+`time_key` time NOT NULL,
+`datetime_nokey` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+KEY `date_key` (`date_key`),
+KEY `time_key` (`time_key`),
+KEY `varchar_key` (`varchar_key`)
+);
+INSERT INTO `B` VALUES ('2003-07-28','2003-07-28','15:13:38','0000-00-00 00:00:00','f'),('0000-00-00','0000-00-00','00:05:48','2004-07-02 14:34:13','x');
+CREATE TABLE `BB` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`date_key` date NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+`date_nokey` date NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `date_key` (`date_key`)
+);
+INSERT INTO `BB` VALUES (10,8,'0000-00-00','i','0000-00-00'),(11,0,'2005-08-18','','2005-08-18');
+SELECT table1 . `pk` AS field1
+FROM
+(BB AS table1 INNER JOIN
+(AA AS table2 STRAIGHT_JOIN A AS table3
+ON ( table3 . `date_key` = table2 . `pk` ))
+ON ( table3 . `datetime_key` = table2 . `int_nokey` ))
+WHERE ( table3 . `date_key` <= 4 AND table2 . `pk` = table1 . `varchar_nokey`)
+GROUP BY field1 ;
+field1
+SELECT table3 .`date_key` field1
+FROM
+B table1 LEFT JOIN B table3 JOIN
+(BB table6 JOIN A table7 ON table6 .`varchar_nokey`)
+ON table6 .`int_nokey` ON table6 .`date_key`
+ WHERE NOT ( table1 .`varchar_key` AND table7 .`pk`) GROUP BY field1;
+field1
+NULL
+SELECT table4 . `time_nokey` AS field1 FROM
+(AA AS table1 CROSS JOIN
+(AA AS table2 STRAIGHT_JOIN
+(B AS table3 STRAIGHT_JOIN A AS table4
+ON ( table4 . `date_key` = table3 . `time_key` ))
+ON ( table4 . `pk` = table3 . `date_nokey` ))
+ON ( table4 . `time_key` = table3 . `datetime_nokey` ))
+WHERE ( table4 . `time_key` < table1 . `time_key` AND
+table1 . `int_nokey` != 'f')
+GROUP BY field1 ORDER BY field1 , field1;
+field1
+SELECT table1 .`time_key` field2 FROM B table1 LEFT JOIN BB JOIN A table5 ON table5 .`date_nokey` ON table5 .`int_nokey` GROUP BY field2;
+field2
+00:05:48
+15:13:38
+drop table A,AA,B,BB;
+#end of test for bug#45266
+#
+# BUG#48052: Valgrind warning - uninitialized value in init_read_record()
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL,
+i int(11) DEFAULT NULL,
+v varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (2,7,'m');
+INSERT INTO t1 VALUES (3,9,'m');
+SELECT v
+FROM t1
+WHERE NOT pk > 0
+HAVING v <= 't'
+ORDER BY pk;
+v
+DROP TABLE t1;
+#
+# Bug#49489 Uninitialized cache led to a wrong result.
+#
+CREATE TABLE t1(c1 DOUBLE(5,4));
+INSERT INTO t1 VALUES (9.1234);
+SELECT * FROM t1 WHERE c1 < 9.12345;
+c1
+9.1234
+DROP TABLE t1;
+# End of test for bug#49489.
+#
+# Bug #49517: Inconsistent behavior while using
+# NULLable BIGINT and INT columns in comparison
+#
+CREATE TABLE t1(a BIGINT UNSIGNED NOT NULL, b BIGINT NULL, c INT NULL);
+INSERT INTO t1 VALUES(105, NULL, NULL);
+SELECT * FROM t1 WHERE b < 102;
+a b c
+SELECT * FROM t1 WHERE c < 102;
+a b c
+SELECT * FROM t1 WHERE 102 < b;
+a b c
+SELECT * FROM t1 WHERE 102 < c;
+a b c
+DROP TABLE t1;
+#
+# Bug #54459: Assertion failed: param.sort_length,
+# file .\filesort.cc, line 149 (part II)
+#
+CREATE TABLE t1(a ENUM('') NOT NULL);
+INSERT INTO t1 VALUES (), (), ();
+EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci;
+1
+1
+1
+1
+DROP TABLE t1;
+End of 5.1 tests
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result
index c1aa5704f56..6d3a3717c67 100644
--- a/mysql-test/r/select_pkeycache.result
+++ b/mysql-test/r/select_pkeycache.result
@@ -185,37 +185,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1391,15 +1391,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1415,15 +1415,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1431,7 +1431,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
@@ -2362,16 +2362,16 @@ insert into t1 values (1,2), (2,2), (3,2), (4,2);
insert into t2 values (1,3), (2,3), (3,4), (4,4);
explain select * from t1 left join t2 on a=c where d in (4);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref c,d d 5 const 2 Using where
-1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ref c,d d 5 const 2
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
select * from t1 left join t2 on a=c where d in (4);
a b c d
3 2 3 4
4 2 4 4
explain select * from t1 left join t2 on a=c where d = 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref c,d d 5 const 2 Using where
-1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ref c,d d 5 const 2
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
select * from t1 left join t2 on a=c where d = 4;
a b c d
3 2 3 4
@@ -2397,11 +2397,11 @@ 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
-1 SIMPLE t2 ref a a 23 test.t1.a 2
+1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE 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
-1 SIMPLE t2 ref a a 23 test.t1.a 2
+1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where
DROP TABLE t1, t2;
CREATE TABLE t1 ( city char(30) );
INSERT INTO t1 VALUES ('London');
@@ -2716,8 +2716,8 @@ explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
t2.b like '%%' order by t2.b limit 0,1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort
-1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
+1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
+1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a int, INDEX idx(a));
@@ -2738,7 +2738,7 @@ ALTER TABLE t1 ENABLE KEYS;
EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b b 5 NULL 2 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
a b a b
1 NULL 1 1
@@ -2748,7 +2748,7 @@ a b a b
EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b b 5 NULL 2 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
a b a b
1 NULL 1 1
@@ -2910,11 +2910,11 @@ a
EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 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
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON 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 3
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
DROP TABLE t1,t2;
select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
@@ -3417,7 +3417,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 where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -3453,7 +3453,7 @@ In next EXPLAIN, B.rows must be exactly 10:
explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using where
+1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using index condition; Using where; Using MRR
1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10
drop table t1, t2;
CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
@@ -3467,13 +3467,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
-1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using MRR
+1 SIMPLE t2 ref c c 5 test.t1.a 2
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
-1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Using MRR
+1 SIMPLE t2 ref c c 5 test.t1.a 2
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,
@@ -3533,7 +3533,7 @@ WHERE t1.id=2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
1 SIMPLE t2 const idx1 NULL NULL NULL 1
-1 SIMPLE t3 ref idx1 idx1 5 const 3 Using where
+1 SIMPLE t3 ref idx1 idx1 5 const 3
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
WHERE t1.id=2;
id a b c d e
@@ -3562,19 +3562,19 @@ EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk < 'c' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Using MRR
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
@@ -3608,7 +3608,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 4 Using where
+1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3616,7 +3616,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee') ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 4 Using where
+1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
@@ -3624,7 +3624,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 2 Using where
+1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3632,7 +3632,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
+1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Using MRR
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
@@ -3752,7 +3752,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range ts ts 4 NULL 1 Using where
+1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where; Using MRR
Warnings:
Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
@@ -3854,7 +3854,7 @@ cc 3 7
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref name name 6 test.t1.name 2
+1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where
SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
name name n
ccc NULL NULL
@@ -3928,7 +3928,7 @@ cc 3 7
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE t2 ref name name 6 test.t1.name 2
+1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where
SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
name name n
ccc NULL NULL
@@ -4376,12 +4376,12 @@ CREATE TABLE t1 (a INT KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Using MRR
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Using MRR
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
@@ -4396,7 +4396,7 @@ INSERT INTO t1 VALUES
EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL a NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2 Range checked for each record (index map: 0x1)
SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
1
1
@@ -4406,7 +4406,7 @@ SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL a NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2 Range checked for each record (index map: 0x1)
SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
1
1
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index feac9efcb13..26fb008c2a0 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -66,13 +66,13 @@ 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");
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
-1 SIMPLE t2 ref b b 21 test.t1.b 6 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 21 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
-1 SIMPLE t2 ref b b 21 test.t1.b 6 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 21 Using where
+1 SIMPLE t2 ref b b 21 test.t1.b 6
SET MAX_SEEKS_FOR_KEY=DEFAULT;
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/shm.result b/mysql-test/r/shm.result
index c504fe222ef..a92efca148b 100644
--- a/mysql-test/r/shm.result
+++ b/mysql-test/r/shm.result
@@ -183,37 +183,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1389,15 +1389,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1413,15 +1413,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result
index 953830ecc87..d974cfb9605 100644
--- a/mysql-test/r/sp-threads.result
+++ b/mysql-test/r/sp-threads.result
@@ -35,7 +35,7 @@ call bug9486();
show processlist;
Id User Host db Command Time State Info
# root localhost test Sleep # NULL
-# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
+# root localhost test Query # Table lock update t1, t2 set val= 1 where id1=id2
# root localhost test Query # NULL show processlist
# root localhost test Sleep # NULL
unlock tables;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 72079ee03a0..9370b63e847 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6418,19 +6418,19 @@ INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
CREATE VIEW v1 AS SELECT c1 FROM t1;
EXPLAIN SELECT * FROM t1 WHERE c1=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
+1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f1();
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
+1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM v1 WHERE c1=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
+1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM v1 WHERE c1=f1();
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
+1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(10);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
+1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(c1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL c1 5 NULL 5 Using where; Using index
diff --git a/mysql-test/r/ssl.result b/mysql-test/r/ssl.result
index 9ad515a53a3..1a52571c2d7 100644
--- a/mysql-test/r/ssl.result
+++ b/mysql-test/r/ssl.result
@@ -186,37 +186,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1392,15 +1392,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1416,15 +1416,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1432,7 +1432,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
diff --git a/mysql-test/r/ssl_compress.result b/mysql-test/r/ssl_compress.result
index 1bd427a65e2..d66b0a3a7f5 100644
--- a/mysql-test/r/ssl_compress.result
+++ b/mysql-test/r/ssl_compress.result
@@ -189,37 +189,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-218401 faithful
+012001 flanking
+013602 foldout
+013606 fingerings
018007 fanatic
-228311 fated
018017 featherweight
-218022 feed
-088303 feminine
-058004 Fenton
-038017 fetched
018054 fetters
-208101 fiftieth
-238007 filial
-013606 fingerings
-218008 finishers
-038205 firearm
-188505 fitting
-202301 Fitzpatrick
-238008 fixedly
-012001 flanking
018103 flint
018104 flopping
+036002 funereal
+038017 fetched
+038205 firearm
+058004 Fenton
+088303 feminine
+186002 freakish
188007 flurried
-013602 foldout
+188505 fitting
+198006 furthermore
+202301 Fitzpatrick
+208101 fiftieth
+208113 freest
+218008 finishers
+218022 feed
+218401 faithful
226205 foothill
-232102 forgivably
+226209 furnishings
228306 forthcoming
-186002 freakish
-208113 freest
+228311 fated
231315 freezes
-036002 funereal
-226209 furnishings
-198006 furthermore
+232102 forgivably
+238007 filial
+238008 fixedly
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -1395,15 +1395,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1419,15 +1419,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1435,7 +1435,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 6710b8fc941..932c8be3dc1 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1,4 +1,7 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
select (select 2);
(select 2)
2
@@ -50,7 +53,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select '1') = 1)
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><'1'>((select '1')) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -314,7 +317,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 `test`.`t1` where ('2' = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+Note 1003 select <expr_cache><`test`.`t2`.`a`>((select '2' from `test`.`t1` where ('2' = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`))) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
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 +335,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;
@@ -719,7 +722,7 @@ id
1
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ref id id 5 const 1 100.00 Using where; Using index
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
Warnings:
Note 1249 Select 2 was reduced during optimization
Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
@@ -731,7 +734,7 @@ id
2
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ref id id 5 const 1 100.00 Using where; Using index
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
Warnings:
Note 1249 Select 3 was reduced during optimization
Note 1249 Select 2 was reduced during optimization
@@ -743,7 +746,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);
@@ -891,7 +894,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;
@@ -903,10 +906,10 @@ a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
-2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 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 1 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 1 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);
@@ -1231,7 +1234,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
+1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1293,36 +1296,40 @@ 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
-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 1 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));
create table t3 (a int, b int, index a (a));
insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
insert into t2 values (2), (3), (4), (5);
insert into t3 values (10,3), (20,4), (30,5);
select * from t2 where t2.a in (select a from t1);
@@ -1332,31 +1339,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 1001 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 101 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 where (<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`)
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 1001 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 101 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 1001 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.61 Using index; FirstMatch(t2)
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 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`.`t1`.`b` = `test`.`t3`.`a`))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1369,11 +1376,11 @@ 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 1001 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 101 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`)))))
-drop table t1, t2, t3;
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+drop table t0, t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
create table t3 (a int, b int);
@@ -1463,25 +1470,25 @@ 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 t3 (a int);
@@ -1736,14 +1743,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');
@@ -1767,7 +1774,7 @@ explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
-1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
Warnings:
Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
drop table t1,t2;
@@ -2279,7 +2286,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);
@@ -2820,19 +2827,20 @@ 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`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
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 subselect2 eq_ref unique_key unique_key 10 func 1 1.00
+2 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` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary; Using filesort
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`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
@@ -2949,7 +2957,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
1 PRIMARY r const PRIMARY PRIMARY 4 const 1
-2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
@@ -2961,7 +2969,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
1 PRIMARY r const PRIMARY PRIMARY 4 const 1
-2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
@@ -3412,7 +3420,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
a b
@@ -3423,7 +3431,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
-2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1 Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
DROP TABLE t1;
create table t1( f1 int,f2 int);
insert into t1 values (1,1),(2,2);
@@ -3554,28 +3562,6 @@ ORDER BY t1.t DESC LIMIT 1);
i1 i2 t i1 i2 t
24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
DROP TABLE t1, t2;
-CREATE TABLE t1 (i INT);
-(SELECT i FROM t1) UNION (SELECT i FROM t1);
-i
-SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
-(
-(SELECT i FROM t1) UNION
-(SELECT i FROM t1)
-);
-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 'UNION
-(SELECT i FROM t1)
-)' at line 3
-SELECT * FROM t1
-WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
-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 'UNION (SELECT i FROM t1)))' at line 2
-explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
-from t1;
-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 'union (select t12.i from t1 t12))
-from t1' at line 1
-explain select * from t1 where not exists
-((select t11.i from t1 t11) union (select t12.i from t1 t12));
-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 'union (select t12.i from t1 t12))' at line 2
-DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
insert into t1 (a) values (FLOOR(rand() * 100));
insert into t1 (a) select FLOOR(rand() * 100) from t1;
@@ -3663,9 +3649,14 @@ FROM t1 GROUP BY t1.a LIMIT 1)
2
2
DROP TABLE t1,t2;
-CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
SET SESSION sort_buffer_size = 32 * 1024;
Warnings:
Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
@@ -3680,7 +3671,7 @@ FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
COUNT(*)
3000
-DROP TABLE t1,t2;
+DROP TABLE t1,t2,t3;
CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
CREATE TABLE t2 (c int);
INSERT INTO t1 VALUES ('aa', 1);
@@ -4213,8 +4204,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 2 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 2 Using where; Using index; FirstMatch(t1)
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
a b
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
@@ -4223,15 +4214,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 2 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 2 Using where; Using index; FirstMatch(t2)
SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
a b
EXPLAIN
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 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 2 Using where; Using index; FirstMatch(t1)
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
a b
DROP TABLE t1,t2;
@@ -4260,37 +4251,20 @@ out_a MIN(b)
1 2
2 4
DROP TABLE t1;
-CREATE TABLE t1 (a INT);
-CREATE TABLE t2 (a INT);
-INSERT INTO t1 VALUES (1),(2);
-INSERT INTO t2 VALUES (1),(2);
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
-2
-2
-2
-EXPLAIN EXTENDED
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
-id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-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`))
-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));
-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 'UNION
-(SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2
-DROP TABLE t1,t2;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
insert into t1 values(1,1),(2,2), (3, 3);
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
set session sort_buffer_size= 33*1024;
select count(*) from t1 where f12 =
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
count(*)
3
-drop table t1,t2;
+drop table t0,t1,t2;
CREATE TABLE t4 (
f7 varchar(32) collate utf8_bin NOT NULL default '',
f10 varchar(32) collate utf8_bin default NULL,
@@ -4350,16 +4324,16 @@ CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
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))
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`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 NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
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))
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`))))))
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
@@ -4436,6 +4410,203 @@ pk int_key
7 3
DROP TABLE t1,t2;
End of 5.0 tests.
+create table t_out (subcase char(3),
+a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+insert into t_out values ('A.1','2a', NULL, '2a');
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+
+Test general IN semantics (not top-level)
+
+case A.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+subcase pred_in pred_not_in
+A.1 0 1
+case A.2 - impossible
+case A.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+subcase pred_in pred_not_in
+A.3 NULL NULL
+case A.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+subcase pred_in pred_not_in
+A.4 0 1
+case B.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+subcase pred_in pred_not_in
+B.1 0 1
+case B.2
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+subcase pred_in pred_not_in
+B.2 1 0
+case B.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+subcase pred_in pred_not_in
+B.3 NULL NULL
+case B.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+subcase pred_in pred_not_in
+B.4 0 1
+
+Test IN as top-level predicate, and
+as non-top level for cases A.3, B.3 (the only cases with NULL result).
+
+case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+drop table t_out;
+drop table t_in;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
@@ -4515,9 +4686,9 @@ INSERT INTO t3 VALUES (1,1,1), (2,32,1);
explain
SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t3 index b,b_2 b 10 NULL 2 Using index
-1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 Using index
-2 DEPENDENT SUBQUERY t2 index b,b_2,c d 5 NULL 1 Using where
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
a incorrect
1 1
@@ -4550,6 +4721,42 @@ DELETE FROM v3;
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
#
create table t1(id integer primary key, g integer, v integer, s char(1));
@@ -4599,6 +4806,7 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
#
# Bug #49512 : subquery with aggregate function crash
# subselect_single_select_engine::exec()
@@ -4761,3 +4969,20 @@ select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result
index 27ec0ccfc0f..9d62d3a54f1 100644
--- a/mysql-test/r/subselect2.result
+++ b/mysql-test/r/subselect2.result
@@ -126,11 +126,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 9 Using where
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 34 test.t2.DOCID 1
1 PRIMARY t4 eq_ref PRIMARY PRIMARY 34 test.t2.DOCTYPEID 1
-2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
-3 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
-4 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
-5 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
-6 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using where
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using where
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
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 468f939c943..78a75776573 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -1,4 +1,5 @@
-drop table if exists t0, t1, t2, t3, t4, t5;
+drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
+set @save_optimizer_switch=@@optimizer_switch;
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
@@ -30,7 +31,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; Using filesort
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);
@@ -39,7 +40,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; Using filesort
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
@@ -63,12 +64,15 @@ Handler_read_rnd_next 11
select ' ^ This must show 11' Z;
Z
^ This must show 11
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
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; Using filesort
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));
insert into t1 values
@@ -92,16 +96,17 @@ 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 5
+Handler_read_rnd_next 11
delete from t2;
insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
+set optimizer_switch='subquery_cache=off';
flush status;
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
oref a Z
@@ -120,6 +125,7 @@ Handler_read_rnd_next 29
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.
+set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
create table t1 (a int, b int, primary key (a));
insert into t1 values (1,1), (3,1),(100,1);
@@ -157,7 +163,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 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)))) 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 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)))) 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
@@ -185,7 +191,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 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `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 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)))))) AS `Z` from `test`.`t3`
drop table t1,t2,t3;
create table t1 (oref int, grp int);
insert into t1 (oref, grp) values
@@ -209,7 +215,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; Using filesort
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);
@@ -241,7 +247,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`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
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
@@ -255,10 +261,10 @@ from t2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 2 100.00 Using where; Full scan on NULL key
-2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer
+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`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
select a,b, oref,
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
from t2;
@@ -303,7 +309,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`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`b` = 10) and (`test`.`t2`.`a` = 10))
drop table t1, t2;
create table t1 (oref char(4), grp int, ie int);
insert into t1 (oref, grp, ie) values
@@ -573,7 +579,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`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2`
drop table t1,t2;
create table t1 (oref char(4), grp int, ie int primary key);
insert into t1 (oref, grp, ie) values
@@ -692,6 +698,8 @@ a MAX(b) test
2 3 h
3 4 i
DROP TABLE t1, t2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int, PRIMARY KEY(b));
INSERT INTO t1 VALUES (1), (NULL), (4);
@@ -703,7 +711,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 1 from `test`.`t1` where ((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)) having <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 1 from `test`.`t1` where ((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)) having <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));
@@ -724,7 +732,7 @@ WHERE t3.name='xxx' AND t2.id=t3.id);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 func 1 Using where; Using index; Full scan on NULL key
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 Using where; Full scan on NULL key
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 Using index condition; Using where; Full scan on NULL key
SELECT * FROM t1
WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
WHERE t3.name='xxx' AND t2.id=t3.id);
@@ -759,6 +767,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where
DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES(1);
CREATE TABLE t2 (placeholder CHAR(11));
@@ -779,6 +788,15 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
1
1
DROP TABLE t1, t2;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1;
+delete from t1;
+load data infile "subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
CREATE TABLE t1 (
pk INT PRIMARY KEY,
int_key INT,
@@ -864,11 +882,18 @@ Level Code Message
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2
Error 1054 Unknown column 'c' in 'field list'
-Note 1003 select `c` AS `c` from (select (select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `t1`.`c`) AS `(SELECT COUNT(a) FROM
+Note 1003 select `c` AS `c` from (select <expr_cache><count(`test`.`t1`.`a`),`test`.`t1`.`c`>((select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `t1`.`c`)) AS `(SELECT COUNT(a) FROM
(SELECT COUNT(b) FROM t1) AS x GROUP BY c
)` from `test`.`t1` group by `test`.`t1`.`b`) `y`
DROP TABLE t1;
End of 5.0 tests
+#
+# BUG#36896: Server crash on SELECT FROM DUAL
+#
+create table t1 (a int);
+select 1 as res from dual where (1) in (select * from t1);
+res
+drop table t1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
@@ -930,6 +955,8 @@ i1 i2
4 NULL
5 0
FLUSH STATUS;
+set @save_optimizer_switch2=@@optimizer_switch;
+set optimizer_switch='subquery_cache=off';
SELECT i1, i2
FROM t1
@@ -944,7 +971,7 @@ i1 i2
# Baseline:
SHOW STATUS LIKE '%Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 17
+Handler_read_rnd_next 18
INSERT INTO t1 VALUES (NULL, NULL);
FLUSH STATUS;
@@ -961,6 +988,450 @@ i1 i2
# (read record from t1, but do not read from t2)
SHOW STATUS LIKE '%Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 18
+Handler_read_rnd_next 19
+set @@optimizer_switch=@save_optimizer_switch2;
DROP TABLE t1,t2;
End of 5.1 tests
+CREATE TABLE t1 (
+a int(11) NOT NULL,
+b int(11) NOT NULL,
+c datetime default NULL,
+PRIMARY KEY (a),
+KEY idx_bc (b,c)
+);
+INSERT INTO t1 VALUES
+(406989,67,'2006-02-23 17:08:46'), (150078,67,'2005-10-26 11:17:45'),
+(406993,67,'2006-02-27 11:20:57'), (245655,67,'2005-12-08 15:59:08'),
+(406994,67,'2006-02-27 11:26:46'), (256,67,NULL),
+(398341,67,'2006-02-20 04:48:44'), (254,67,NULL),(1120,67,NULL),
+(406988,67,'2006-02-23 17:07:22'), (255,67,NULL),
+(398340,67,'2006-02-20 04:38:53'),(406631,67,'2006-02-23 10:49:42'),
+(245653,67,'2005-12-08 15:59:07'),(406992,67,'2006-02-24 16:47:18'),
+(245654,67,'2005-12-08 15:59:08'),(406995,67,'2006-02-28 11:55:00'),
+(127261,67,'2005-10-13 12:17:58'),(406991,67,'2006-02-24 16:42:32'),
+(245652,67,'2005-12-08 15:58:27'),(398545,67,'2006-02-20 04:53:13'),
+(154504,67,'2005-10-28 11:53:01'),(9199,67,NULL),(1,67,'2006-02-23 15:01:35'),
+(223456,67,NULL),(4101,67,NULL),(1133,67,NULL),
+(406990,67,'2006-02-23 18:01:45'),(148815,67,'2005-10-25 15:34:17'),
+(148812,67,'2005-10-25 15:30:01'),(245651,67,'2005-12-08 15:58:27'),
+(154503,67,'2005-10-28 11:52:38');
+create table t11 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc;
+create table t12 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc;
+create table t21 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 asc;
+create table t22 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc;
+update t22 set c = '2005-12-08 15:58:27' where a = 255;
+explain select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
+1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
+2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+a b c
+256 67 NULL
+drop table t1, t11, t12, t21, t22;
+create table t1(a int);
+insert into t1 values (0),(1);
+set @@optimizer_switch='firstmatch=off';
+explain
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY X ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY Y ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY subselect3 eq_ref unique_key unique_key 5 func 1
+3 SUBQUERY Z ALL NULL NULL NULL NULL 2
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+subq
+NULL
+0
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select * from t0;
+insert into t1 select a+10 from t0;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+insert into t0 values(2);
+explain select * from t1 where 2 in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; Start temporary; End temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+select * from t1 where 2 in (select a from t0);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+set @@optimizer_switch='default,materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+select * from t1 where 2 in (select a from t0);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+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 subselect3 eq_ref unique_key unique_key 5 func 1
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 20
+2 DERIVED t0 ALL NULL NULL NULL NULL 11
+drop table t0, t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2));
+insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C;
+insert into t1 select * from t1 where kp1 < 20;
+create table t3 (a int);
+insert into t3 select A.a + 10*B.a from t0 A, t0 B;
+explain select * from t3 where a in (select kp1 from t1 where kp1<20);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using where; Using index
+create table t4 (pk int primary key);
+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
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR
+2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index
+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;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+set @@max_heap_table_size= 16384;
+explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
+1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join)
+flush status;
+select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+count(*)
+5000
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+set @save_max_heap_table_size=@@max_heap_table_size;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a int);
+insert into t2 values (1),(2);
+create table t3 ( a int , filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
+explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
+1 PRIMARY t3 ref a a 5 test.t2.a 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+select * from t3 where a in (select a from t2);
+a filler
+1 filler
+2 filler
+drop table t0, t2, t3;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+create table t1 (a date);
+insert into t1 values ('2008-01-01'),('2008-01-01'),('2008-02-01'),('2008-02-01');
+create table t2 (a int);
+insert into t2 values (1),(2);
+create table t3 (a char(10));
+insert into t3 select * from t1;
+insert into t3 values (1),(2);
+explain select * from t2 where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+explain select * from t2 where a 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 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+explain select * from t2 where a in (select a from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+explain select * from t1 where a in (select a from t3);
+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 t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+drop table t1, t2, t3;
+create table t1 (a decimal);
+insert into t1 values (1),(2);
+explain select * from t1 where a 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 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 as select * from t1;
+create table t3 (a int, b int, filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t1 A, t1 B, t1 C;
+explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref a a 5 test.t2.a 10
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+2 SUBQUERY A ALL NULL NULL NULL NULL 10
+2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+2 SUBQUERY A ALL NULL NULL NULL NULL 10
+2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+explain select straight_join * from t2 X, t2 Y
+where X.a in (select straight_join A.a from t1 A, t1 B);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+2 SUBQUERY A ALL NULL NULL NULL NULL 10
+2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+create table t0 (a int, b int);
+insert into t0 values(1,1);
+explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 system NULL NULL NULL NULL 1
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref a a 5 test.t2.a 10
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+create table t4 as select a as x, a as y from t1;
+explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 system NULL NULL NULL NULL 1
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where
+2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
+drop table t0,t1,t2,t3,t4;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, filler char(100), key(a,b));
+insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B;
+create table t2 as select * from t1;
+explain select * from t2 where a in (select b from t1 where a=3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
+explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
+1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
+drop table t1,t2;
+create table t1 (a int, b int);
+insert into t1 select a,a from t0;
+create table t2 (a int, b int);
+insert into t2 select A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B;
+set @@optimizer_switch='firstmatch=off';
+explain select * from t1 where (a,b) 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 10
+1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
+set @save_optimizer_search_depth=@@optimizer_search_depth;
+set @@optimizer_search_depth=63;
+explain select * from t1 where (a,b) 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 10
+1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
+set @@optimizer_search_depth=@save_optimizer_search_depth;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+create table t0 (a decimal(4,2));
+insert into t0 values (10.24), (22.11);
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
+select * from t0 where a in (select a from t1);
+a
+10.24
+22.11
+drop table t0, t1;
+create table t0(a date);
+insert into t0 values ('2008-01-01'),('2008-02-02');
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
+select * from t0 where a in (select a from t1);
+a
+2008-01-01
+2008-02-02
+drop table t0, t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select a as a, a as b, a as c from t0 where a < 3;
+create table t2 as select a as a, a as b from t0 where a < 3;
+insert into t2 select * from t2;
+explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
+2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+drop table t0,t1,t2;
+
+BUG#37842: Assertion in DsMrr_impl::dsmrr_init, at handler.cc:4307
+
+CREATE TABLE t1 (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_key` int(11) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,9),(2,3),(3,8),(4,6),(5,9),(6,5),(7,5),(8,9),(9,1),(10,10);
+SELECT `pk` FROM t1 AS OUTR WHERE `int_key` = ALL (
+SELECT `int_key` FROM t1 AS INNR WHERE INNR . `pk` >= 9
+);
+pk
+DROP TABLE t1;
+
+BUG#40118 Crash when running Batched Key Access and requiring one match for each key
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, key(a));
+insert into t1 select * from t0;
+alter table t1 add b int not null, add filler char(200);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+select * from t0 where t0.a in (select t1.a from t1 where t1.b=0);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+set join_cache_level=@save_join_cache_level;
+drop table t0, t1;
+#
+# BUG#32665 Query with dependent subquery is too slow
+#
+create table t1 (
+idIndividual int primary key
+);
+insert into t1 values (1),(2);
+create table t2 (
+idContact int primary key,
+contactType int,
+idObj int
+);
+insert into t2 values (1,1,1),(2,2,2),(3,3,3);
+create table t3 (
+idAddress int primary key,
+idContact int,
+postalStripped varchar(100)
+);
+insert into t3 values (1,1, 'foo'), (2,2,'bar');
+The following must be converted to a semi-join:
+explain extended SELECT a.idIndividual FROM t1 a
+WHERE a.idIndividual IN
+( SELECT c.idObj FROM t3 cona
+INNER JOIN t2 c ON c.idContact=cona.idContact
+WHERE cona.postalStripped='T2H3B2'
+ );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
+1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00
+Warnings:
+Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`c`.`idContact` = `test`.`cona`.`idContact`) and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`cona`.`postalStripped` = 'T2H3B2'))
+drop table t1,t2,t3;
+#
+# BUG#47367 Crash in Name_resolution_context::process_error
+#
+SET SESSION optimizer_switch = 'default,semijoin=off';
+CREATE TABLE t1 (f1 INTEGER);
+CREATE TABLE t2 LIKE t1;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+CALL p1;
+f1
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+CALL p1;
+f1
+DROP PROCEDURE p1;
+# Restore the original column list of table t2:
+ALTER TABLE t2 CHANGE COLUMN my_column f1 INT;
+SET SESSION optimizer_switch = 'semijoin=on';
+# Recreate procedure so that we eliminate any caching effects
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+CALL p1;
+f1
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+CALL p1;
+ERROR 42S22: Unknown column 'f1' in 'where clause'
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result
new file mode 100644
index 00000000000..f866f1c2aa9
--- /dev/null
+++ b/mysql-test/r/subselect3_jcl6.result
@@ -0,0 +1,1449 @@
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
+set @save_optimizer_switch=@@optimizer_switch;
+create table t1 (oref int, grp int, ie int) ;
+insert into t1 (oref, grp, ie) values
+(1, 1, 1),
+(1, 1, 1),
+(1, 2, NULL),
+(2, 1, 3),
+(3, 1, 4),
+(3, 2, NULL);
+create table t2 (oref int, a int);
+insert into t2 values
+(1, 1),
+(2, 2),
+(3, 3),
+(4, NULL),
+(2, NULL);
+select a, oref, a in (select max(ie)
+from t1 where oref=t2.oref group by grp) Z from t2;
+a oref Z
+1 1 1
+2 2 0
+3 3 NULL
+NULL 4 0
+NULL 2 NULL
+explain extended
+select a, oref, a in (select max(ie)
+from t1 where oref=t2.oref group by grp) Z from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary; Using filesort
+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`,<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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary; Using filesort
+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 <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
+) Z from t2;
+a oref Z
+1 1 1
+2 2 0
+3 3 NULL
+NULL 4 0
+NULL 2 NULL
+create table t3 (a int);
+insert into t3 values (NULL), (NULL);
+flush status;
+select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
+a in (select max(ie) from t1 where oref=4 group by grp)
+0
+0
+show status like 'Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 11
+select ' ^ This must show 11' Z;
+Z
+ ^ This must show 11
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
+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; Using filesort
+Warnings:
+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));
+insert into t1 values
+(1, 1),
+(1, NULL),
+(2, 3),
+(2, NULL),
+(3, NULL);
+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;
+oref a Z
+1 1 1
+2 2 0
+3 NULL NULL
+4 NULL 0
+explain extended
+select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 4 100.00
+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`,<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
+delete from t2;
+insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
+set optimizer_switch='subquery_cache=off';
+flush status;
+select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
+oref a Z
+0 NULL 0
+0 NULL 0
+0 NULL 0
+0 NULL 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 29
+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.
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+create table t1 (a int, b int, primary key (a));
+insert into t1 values (1,1), (3,1),(100,1);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,1),(NULL,1),(NULL,0);
+select a,b, a in (select a from t1 where t1.b = t2.b) Z from t2 ;
+a b Z
+1 1 1
+2 1 0
+NULL 1 NULL
+NULL 0 0
+drop table t1, t2;
+create table t1 (a int, b int, key(a));
+insert into t1 values
+(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+create table t2 like t1;
+insert into t2 select * from t1;
+update t2 set b=1;
+create table t3 (a int, oref int);
+insert into t3 values (1, 1), (NULL,1), (NULL,0);
+select a, oref,
+t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
+from t3;
+a oref Z
+1 1 1
+NULL 1 NULL
+NULL 0 0
+explain extended
+select a, oref,
+t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
+from t3;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 4 100.00 Using where; Full scan on NULL key
+2 DEPENDENT SUBQUERY t2 ref a a 5 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join)
+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`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)))) 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
+(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+create table t2 like t1;
+insert into t2 select * from t1;
+update t2 set b=1;
+create table t3 (a int, oref int);
+insert into t3 values (1, 1), (NULL,1), (NULL,0);
+select a, oref,
+t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
+from t3;
+a oref Z
+1 1 1
+NULL 1 NULL
+NULL 0 0
+This must show a trig_cond:
+explain extended
+select a, oref,
+t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
+from t3;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t1 ref a a 4 func 2 100.00 Using where; Full scan on NULL key
+2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join)
+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`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)))))) AS `Z` from `test`.`t3`
+drop table t1,t2,t3;
+create table t1 (oref int, grp int);
+insert into t1 (oref, grp) values
+(1, 1),
+(1, 1);
+create table t2 (oref int, a int);
+insert into t2 values
+(1, NULL),
+(2, NULL);
+select a, oref,
+a in (select count(*) from t1 group by grp having grp=t2.oref) Z from t2;
+a oref Z
+NULL 1 NULL
+NULL 2 0
+This must show a trig_cond:
+explain extended
+select a, oref,
+a in (select count(*) from t1 group by grp having grp=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+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`,<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);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,1),(NULL,1),(NULL,0);
+select a,b, a in (select a from t1 where t1.b = t2.b union select a from
+t1 where t1.b = t2.b) Z from t2 ;
+a b Z
+1 1 1
+2 1 0
+NULL 1 NULL
+NULL 0 0
+select a,b, a in (select a from t1 where t1.b = t2.b) Z from t2 ;
+a b Z
+1 1 1
+2 1 0
+NULL 1 NULL
+NULL 0 0
+drop table t1, t2;
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, oref int);
+insert into t2 values (NULL,1, 100), (NULL,2, 100);
+create table t1 (a int, b int, c int, key(a,b));
+insert into t1 select 2*A, 2*A, 100 from t3;
+explain extended select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 100.00 Using where; Full scan on NULL key
+Warnings:
+Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
+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
+NULL 2 100 NULL
+create table t4 (x int);
+insert into t4 select A.a + 10*B.a from t1 A, t1 B;
+explain extended
+select a,b, oref,
+(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
+from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 2 100.00 Using where; Full scan on NULL key
+2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
+select a,b, oref,
+(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
+from t2;
+a b oref Z
+NULL 1 100 0
+NULL 2 100 NULL
+drop table t1,t2,t3,t4;
+create table t1 (oref char(4), grp int, ie1 int, ie2 int);
+insert into t1 (oref, grp, ie1, ie2) values
+('aa', 10, 2, 1),
+('aa', 10, 1, 1),
+('aa', 20, 2, 1),
+('bb', 10, 3, 1),
+('cc', 10, 4, 2),
+('cc', 20, 3, 2),
+('ee', 10, 2, 1),
+('ee', 10, 1, 2),
+('ff', 20, 2, 2),
+('ff', 20, 1, 2);
+create table t2 (oref char(4), a int, b int);
+insert into t2 values
+('ee', NULL, 1),
+('bb', 2, 1),
+('ff', 2, 2),
+('cc', 3, NULL),
+('bb', NULL, NULL),
+('aa', 1, 1),
+('dd', 1, NULL);
+alter table t1 add index idx(ie1,ie2);
+select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=3 and b is null ;
+oref a b Z
+cc 3 NULL NULL
+insert into t2 values ('new1', 10,10);
+insert into t1 values ('new1', 1234, 10, NULL);
+select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
+oref a b Z
+new1 10 10 NULL
+explain extended
+select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 8 100.00 Using where
+2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 100.00 Using where; Full scan on NULL key
+Warnings:
+Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`b` = 10) and (`test`.`t2`.`a` = 10))
+drop table t1, t2;
+create table t1 (oref char(4), grp int, ie int);
+insert into t1 (oref, grp, ie) values
+('aa', 10, 2),
+('aa', 10, 1),
+('aa', 20, NULL),
+('bb', 10, 3),
+('cc', 10, 4),
+('cc', 20, NULL),
+('ee', 10, NULL),
+('ee', 10, NULL),
+('ff', 20, 2),
+('ff', 20, 1);
+create table t2 (oref char(4), a int);
+insert into t2 values
+('ee', NULL),
+('bb', 2),
+('ff', 2),
+('cc', 3),
+('aa', 1),
+('dd', NULL),
+('bb', NULL);
+select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+oref a Z
+ee NULL NULL
+bb 2 0
+ff 2 1
+cc 3 NULL
+aa 1 1
+dd NULL 0
+bb NULL NULL
+select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
+oref a
+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
+dd NULL
+select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
+oref a Z
+ee NULL NULL
+bb 2 0
+ff 2 0
+cc 3 NULL
+aa 1 1
+dd NULL 0
+bb NULL NULL
+select oref, a from t2 where
+a in (select min(ie) from t1 where oref=t2.oref group by grp);
+oref a
+aa 1
+select oref, a from t2 where
+a not in (select min(ie) from t1 where oref=t2.oref group by grp);
+oref a
+bb 2
+ff 2
+dd NULL
+update t1 set ie=3 where oref='ff' and ie=1;
+select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by
+grp) Z from t2;
+oref a Z
+ee NULL NULL
+bb 2 0
+ff 2 1
+cc 3 NULL
+aa 1 1
+dd NULL 0
+bb NULL NULL
+select oref, a from t2 where a in (select min(ie) from t1 where
+oref=t2.oref group by grp);
+oref a
+ff 2
+aa 1
+select oref, a from t2 where a not in (select min(ie) from t1 where
+oref=t2.oref group by grp);
+oref a
+bb 2
+dd NULL
+select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by
+grp having min(ie) > 1) Z from t2;
+oref a Z
+ee NULL 0
+bb 2 0
+ff 2 1
+cc 3 0
+aa 1 0
+dd NULL 0
+bb NULL NULL
+select oref, a from t2 where a in (select min(ie) from t1 where
+oref=t2.oref group by grp having min(ie) > 1);
+oref a
+ff 2
+select oref, a from t2 where a not in (select min(ie) from t1 where
+oref=t2.oref group by grp having min(ie) > 1);
+oref a
+ee NULL
+bb 2
+cc 3
+aa 1
+dd NULL
+alter table t1 add index idx(ie);
+explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 Using where; Full scan on NULL key
+select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+oref a Z
+ee NULL NULL
+bb 2 0
+ff 2 1
+cc 3 NULL
+aa 1 1
+dd NULL 0
+bb NULL NULL
+select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
+oref a
+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
+dd NULL
+alter table t1 drop index idx;
+alter table t1 add index idx(oref,ie);
+explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+2 DEPENDENT SUBQUERY t1 ref_or_null idx idx 10 test.t2.oref,func 4 Using where; Using index; Full scan on NULL key
+select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+oref a Z
+ee NULL NULL
+bb 2 0
+ff 2 1
+cc 3 NULL
+aa 1 1
+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
+select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
+oref a
+bb 2
+dd NULL
+explain
+select oref, a,
+a in (select min(ie) from t1 where oref=t2.oref
+group by grp having min(ie) > 1) Z
+from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+2 DEPENDENT SUBQUERY t1 ref idx idx 5 test.t2.oref 2 Using where; Using temporary; Using filesort
+select oref, a,
+a in (select min(ie) from t1 where oref=t2.oref
+group by grp having min(ie) > 1) Z
+from t2;
+oref a Z
+ee NULL 0
+bb 2 0
+ff 2 1
+cc 3 0
+aa 1 0
+dd NULL 0
+bb NULL NULL
+select oref, a from t2 where a in (select min(ie) from t1 where oref=t2.oref
+group by grp having min(ie) > 1);
+oref a
+ff 2
+select oref, a from t2 where a not in (select min(ie) from t1 where oref=t2.oref
+group by grp having min(ie) > 1);
+oref a
+ee NULL
+bb 2
+cc 3
+aa 1
+dd NULL
+drop table t1,t2;
+create table t1 (oref char(4), grp int, ie1 int, ie2 int);
+insert into t1 (oref, grp, ie1, ie2) values
+('aa', 10, 2, 1),
+('aa', 10, 1, 1),
+('aa', 20, 2, 1),
+('bb', 10, 3, 1),
+('cc', 10, 4, 2),
+('cc', 20, 3, 2),
+('ee', 10, 2, 1),
+('ee', 10, 1, 2),
+('ff', 20, 2, 2),
+('ff', 20, 1, 2);
+create table t2 (oref char(4), a int, b int);
+insert into t2 values
+('ee', NULL, 1),
+('bb', 2, 1),
+('ff', 2, 2),
+('cc', 3, NULL),
+('bb', NULL, NULL),
+('aa', 1, 1),
+('dd', 1, NULL);
+select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
+oref a b Z
+ee NULL 1 NULL
+bb 2 1 0
+ff 2 2 1
+cc 3 NULL NULL
+bb NULL NULL NULL
+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
+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
+dd 1 NULL
+select oref, a, b,
+(a,b) in (select min(ie1),max(ie2) from t1
+where oref=t2.oref group by grp) Z
+from t2;
+oref a b Z
+ee NULL 1 0
+bb 2 1 0
+ff 2 2 0
+cc 3 NULL NULL
+bb NULL NULL NULL
+aa 1 1 1
+dd 1 NULL 0
+select oref, a, b from t2 where
+(a,b) in (select min(ie1), max(ie2) from t1 where oref=t2.oref group by grp);
+oref a b
+aa 1 1
+select oref, a, b from t2 where
+(a,b) not in (select min(ie1), max(ie2) from t1 where oref=t2.oref group by grp);
+oref a b
+ee NULL 1
+bb 2 1
+ff 2 2
+dd 1 NULL
+alter table t1 add index idx(ie1,ie2);
+explain select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 Using where; Full scan on NULL key
+select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
+oref a b Z
+ee NULL 1 NULL
+bb 2 1 0
+ff 2 2 1
+cc 3 NULL NULL
+bb NULL NULL NULL
+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
+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
+dd 1 NULL
+explain extended
+select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7 100.00
+2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 100.00 Using where; Full scan on NULL key
+Warnings:
+Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2`
+drop table t1,t2;
+create table t1 (oref char(4), grp int, ie int primary key);
+insert into t1 (oref, grp, ie) values
+('aa', 10, 2),
+('aa', 10, 1),
+('bb', 10, 3),
+('cc', 10, 4),
+('cc', 20, 5),
+('cc', 10, 6);
+create table t2 (oref char(4), a int);
+insert into t2 values
+('ee', NULL),
+('bb', 2),
+('cc', 5),
+('cc', 2),
+('cc', NULL),
+('aa', 1),
+('bb', NULL);
+explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using where; Full scan on NULL key
+select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
+oref a Z
+ee NULL 0
+bb 2 0
+cc 5 1
+cc 2 0
+cc NULL NULL
+aa 1 1
+bb NULL NULL
+select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
+oref a
+aa 1
+cc 5
+select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
+oref a
+ee NULL
+bb 2
+cc 2
+explain
+select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 Using where; Using temporary; Using filesort
+select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
+oref a Z
+ee NULL 0
+bb 2 0
+cc 5 1
+cc 2 0
+cc NULL NULL
+aa 1 1
+bb NULL NULL
+drop table t1,t2;
+create table t1 (a int, b int);
+insert into t1 values (0,0), (2,2), (3,3);
+create table t2 (a int, b int);
+insert into t2 values (1,1), (3,3);
+select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
+a b Z
+0 0 0
+2 2 0
+3 3 1
+insert into t2 values (NULL,4);
+select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
+a b Z
+0 0 0
+2 2 0
+3 3 1
+drop table t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'),(3,3,'j'), (3,2,'k'), (3,1,'l'),
+(1,9,'m');
+CREATE TABLE t2 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t2 SELECT * FROM t1;
+SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
+as test FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT * FROM t1 GROUP by t1.a
+HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
+HAVING MAX(t2.b+t1.a) < 10));
+a b c
+SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
+a b c
+1 3 c
+2 3 h
+3 3 j
+1 4 d
+3 4 i
+1 9 m
+SELECT a, MAX(b),
+(SELECT COUNT(DISTINCT t.c) FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)
+LIMIT 1)
+as cnt,
+(SELECT t.b FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
+as t_b,
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
+as t_b,
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) ORDER BY t.c LIMIT 1)
+as t_b
+FROM t1 GROUP BY a;
+a MAX(b) cnt t_b t_b t_b
+1 9 1 9 m m
+2 3 1 3 h h
+3 4 1 4 i i
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1, t2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int, PRIMARY KEY(b));
+INSERT INTO t1 VALUES (1), (NULL), (4);
+INSERT INTO t2 VALUES (3), (1),(2), (5), (4), (7), (6);
+EXPLAIN EXTENDED
+SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+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(<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t1` where ((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)) having <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));
+a
+1
+4
+DROP TABLE t1,t2;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int PRIMARY KEY);
+CREATE TABLE t3 (id int PRIMARY KEY, name varchar(10));
+INSERT INTO t1 VALUES (2), (NULL), (3), (1);
+INSERT INTO t2 VALUES (234), (345), (457);
+INSERT INTO t3 VALUES (222,'bbb'), (333,'ccc'), (111,'aaa');
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
+WHERE t3.name='xxx' AND t2.id=t3.id);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 func 1 Using where; Using index; Full scan on NULL key
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 Using index condition(BKA); Using where; Full scan on NULL key; Using join buffer (flat, BKA join)
+SELECT * FROM t1
+WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
+WHERE t3.name='xxx' AND t2.id=t3.id);
+id
+2
+NULL
+3
+1
+SELECT (t1.id IN (SELECT t2.id FROM t2,t3
+WHERE t3.name='xxx' AND t2.id=t3.id)) AS x
+FROM t1;
+x
+0
+0
+0
+0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(-1), (65),(66);
+CREATE TABLE t2 (a INT UNSIGNED NOT NULL PRIMARY KEY);
+INSERT INTO t2 VALUES (65),(66);
+SELECT a FROM t1 WHERE a NOT IN (65,66);
+a
+1
+-1
+SELECT a FROM t1 WHERE a NOT IN (SELECT a FROM t2);
+a
+1
+-1
+EXPLAIN SELECT a FROM t1 WHERE a NOT IN (SELECT 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 Using where
+2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where
+DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES(1);
+CREATE TABLE t2 (placeholder CHAR(11));
+INSERT INTO t2 VALUES("placeholder");
+SELECT ROW(1, 2) IN (SELECT t1.a, 2) FROM t1 GROUP BY t1.a;
+ROW(1, 2) IN (SELECT t1.a, 2)
+1
+SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a;
+ROW(1, 2) IN (SELECT t1.a, 2 FROM t2)
+1
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE TABLE t2 SELECT * FROM t1;
+SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
+1
+1
+1
+1
+DROP TABLE t1, t2;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1;
+delete from t1;
+load data infile "subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE t1 (
+pk INT PRIMARY KEY,
+int_key INT,
+varchar_key VARCHAR(5) UNIQUE,
+varchar_nokey VARCHAR(5)
+);
+INSERT INTO t1 VALUES (9, 7,NULL,NULL), (10,8,'p' ,'p');
+SELECT varchar_nokey
+FROM t1
+WHERE NULL NOT IN (
+SELECT INNR.pk FROM t1 AS INNR2
+LEFT JOIN t1 AS INNR ON ( INNR2.int_key = INNR.int_key )
+WHERE INNR.varchar_key > 'n{'
+);
+varchar_nokey
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2), (11);
+# 2nd and 3rd columns should be same
+SELECT a, ROW(11, 12) = (SELECT a, 22), ROW(11, 12) IN (SELECT a, 22) FROM t1 GROUP BY t1.a;
+a ROW(11, 12) = (SELECT a, 22) ROW(11, 12) IN (SELECT a, 22)
+1 0 0
+2 0 0
+11 0 0
+SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1 GROUP BY t1.a;
+a ROW(11, 12) = (SELECT a, 12) ROW(11, 12) IN (SELECT a, 12)
+1 0 0
+2 0 0
+11 1 1
+SELECT a, ROW(11, 12) = (SELECT a, 22), ROW(11, 12) IN (SELECT a, 22) FROM t1;
+a ROW(11, 12) = (SELECT a, 22) ROW(11, 12) IN (SELECT a, 22)
+1 0 0
+2 0 0
+11 0 0
+SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1;
+a ROW(11, 12) = (SELECT a, 12) ROW(11, 12) IN (SELECT a, 12)
+1 0 0
+2 0 0
+11 1 1
+SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 22), ROW(11, 12) IN (SELECT MAX(x), 22) FROM t1;
+x ROW(11, 12) = (SELECT MAX(x), 22) ROW(11, 12) IN (SELECT MAX(x), 22)
+1 0 0
+2 0 0
+11 0 0
+# 2nd and 3rd columns should be same for x == 11 only
+SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1;
+x ROW(11, 12) = (SELECT MAX(x), 12) ROW(11, 12) IN (SELECT MAX(x), 12)
+1 0 1
+2 0 1
+11 1 1
+DROP TABLE t1;
+# both columns should be same
+SELECT ROW(1,2) = (SELECT NULL, NULL), ROW(1,2) IN (SELECT NULL, NULL);
+ROW(1,2) = (SELECT NULL, NULL) ROW(1,2) IN (SELECT NULL, NULL)
+NULL NULL
+SELECT ROW(1,2) = (SELECT 1, NULL), ROW(1,2) IN (SELECT 1, NULL);
+ROW(1,2) = (SELECT 1, NULL) ROW(1,2) IN (SELECT 1, NULL)
+NULL NULL
+SELECT ROW(1,2) = (SELECT NULL, 2), ROW(1,2) IN (SELECT NULL, 2);
+ROW(1,2) = (SELECT NULL, 2) ROW(1,2) IN (SELECT NULL, 2)
+NULL NULL
+SELECT ROW(1,2) = (SELECT NULL, 1), ROW(1,2) IN (SELECT NULL, 1);
+ROW(1,2) = (SELECT NULL, 1) ROW(1,2) IN (SELECT NULL, 1)
+0 0
+SELECT ROW(1,2) = (SELECT 1, 1), ROW(1,2) IN (SELECT 1, 1);
+ROW(1,2) = (SELECT 1, 1) ROW(1,2) IN (SELECT 1, 1)
+0 0
+SELECT ROW(1,2) = (SELECT 1, 2), ROW(1,2) IN (SELECT 1, 2);
+ROW(1,2) = (SELECT 1, 2) ROW(1,2) IN (SELECT 1, 2)
+1 1
+CREATE TABLE t1 (a INT, b INT, c INT);
+INSERT INTO t1 VALUES (1,1,1), (1,1,1);
+EXPLAIN EXTENDED
+SELECT c FROM
+( SELECT
+(SELECT COUNT(a) FROM
+(SELECT COUNT(b) FROM t1) AS x GROUP BY c
+) FROM t1 GROUP BY b
+) AS y;
+ERROR 42S22: Unknown column 'c' in 'field list'
+SHOW WARNINGS;
+Level Code Message
+Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
+Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2
+Error 1054 Unknown column 'c' in 'field list'
+Note 1003 select `c` AS `c` from (select <expr_cache><count(`test`.`t1`.`a`),`test`.`t1`.`c`>((select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `t1`.`c`)) AS `(SELECT COUNT(a) FROM
+(SELECT COUNT(b) FROM t1) AS x GROUP BY c
+)` from `test`.`t1` group by `test`.`t1`.`b`) `y`
+DROP TABLE t1;
+End of 5.0 tests
+#
+# BUG#36896: Server crash on SELECT FROM DUAL
+#
+create table t1 (a int);
+select 1 as res from dual where (1) in (select * from t1);
+res
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+a int(11) default null,
+b int(11) default null,
+key (a)
+);
+insert into t1 select A.a+10*(B.a+10*C.a),A.a+10*(B.a+10*C.a) from t0 A, t0 B, t0 C;
+create table t2 (a int(11) default null);
+insert into t2 values (0),(1);
+create table t3 (a int(11) default null);
+insert into t3 values (0),(1);
+create table t4 (a int(11) default null);
+insert into t4 values (0),(1);
+create table t5 (a int(11) default null);
+insert into t5 values (0),(1),(0),(1);
+select * from t2, t3
+where
+t2.a < 10 and
+t3.a+1 = 2 and
+t3.a in (select t1.b from t1
+where t1.a+1=t1.a+1 and
+t1.a < (select t4.a+10
+from t4, t5 limit 2));
+ERROR 21000: Subquery returns more than 1 row
+drop table t0, t1, t2, t3, t4, t5;
+#
+# BUG#48177 - SELECTs with NOT IN subqueries containing NULL
+# values return too many records
+#
+CREATE TABLE t1 (
+i1 int DEFAULT NULL,
+i2 int DEFAULT NULL
+) ;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 3);
+INSERT INTO t1 VALUES (4, NULL);
+INSERT INTO t1 VALUES (4, 0);
+INSERT INTO t1 VALUES (NULL, NULL);
+CREATE TABLE t2 (
+i1 int DEFAULT NULL,
+i2 int DEFAULT NULL
+) ;
+INSERT INTO t2 VALUES (4, NULL);
+INSERT INTO t2 VALUES (5, 0);
+
+Data in t1
+SELECT i1, i2 FROM t1;
+i1 i2
+1 NULL
+2 3
+4 NULL
+4 0
+NULL NULL
+
+Data in subquery (should be filtered out)
+SELECT i1, i2 FROM t2 ORDER BY i1;
+i1 i2
+4 NULL
+5 0
+FLUSH STATUS;
+set @save_optimizer_switch2=@@optimizer_switch;
+set optimizer_switch='subquery_cache=off';
+
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+NOT IN (SELECT i1, i2 FROM t2);
+i1 i2
+1 NULL
+2 3
+
+# Check that the subquery only has to be evaluated once
+# for all-NULL values even though there are two (NULL,NULL) records
+# Baseline:
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 18
+
+INSERT INTO t1 VALUES (NULL, NULL);
+FLUSH STATUS;
+
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+NOT IN (SELECT i1, i2 FROM t2);
+i1 i2
+1 NULL
+2 3
+
+# Handler_read_rnd_next should be one more than baseline
+# (read record from t1, but do not read from t2)
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 19
+set @@optimizer_switch=@save_optimizer_switch2;
+DROP TABLE t1,t2;
+End of 5.1 tests
+CREATE TABLE t1 (
+a int(11) NOT NULL,
+b int(11) NOT NULL,
+c datetime default NULL,
+PRIMARY KEY (a),
+KEY idx_bc (b,c)
+);
+INSERT INTO t1 VALUES
+(406989,67,'2006-02-23 17:08:46'), (150078,67,'2005-10-26 11:17:45'),
+(406993,67,'2006-02-27 11:20:57'), (245655,67,'2005-12-08 15:59:08'),
+(406994,67,'2006-02-27 11:26:46'), (256,67,NULL),
+(398341,67,'2006-02-20 04:48:44'), (254,67,NULL),(1120,67,NULL),
+(406988,67,'2006-02-23 17:07:22'), (255,67,NULL),
+(398340,67,'2006-02-20 04:38:53'),(406631,67,'2006-02-23 10:49:42'),
+(245653,67,'2005-12-08 15:59:07'),(406992,67,'2006-02-24 16:47:18'),
+(245654,67,'2005-12-08 15:59:08'),(406995,67,'2006-02-28 11:55:00'),
+(127261,67,'2005-10-13 12:17:58'),(406991,67,'2006-02-24 16:42:32'),
+(245652,67,'2005-12-08 15:58:27'),(398545,67,'2006-02-20 04:53:13'),
+(154504,67,'2005-10-28 11:53:01'),(9199,67,NULL),(1,67,'2006-02-23 15:01:35'),
+(223456,67,NULL),(4101,67,NULL),(1133,67,NULL),
+(406990,67,'2006-02-23 18:01:45'),(148815,67,'2005-10-25 15:34:17'),
+(148812,67,'2005-10-25 15:30:01'),(245651,67,'2005-12-08 15:58:27'),
+(154503,67,'2005-10-28 11:52:38');
+create table t11 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc;
+create table t12 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc;
+create table t21 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 asc;
+create table t22 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc;
+update t22 set c = '2005-12-08 15:58:27' where a = 255;
+explain select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
+1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (incremental, BNL join)
+2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
+2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+a b c
+256 67 NULL
+drop table t1, t11, t12, t21, t22;
+create table t1(a int);
+insert into t1 values (0),(1);
+set @@optimizer_switch='firstmatch=off';
+explain
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY X ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY Y ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY subselect3 eq_ref unique_key unique_key 5 func 1
+3 SUBQUERY Z ALL NULL NULL NULL NULL 2
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+subq
+NULL
+0
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select * from t0;
+insert into t1 select a+10 from t0;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+insert into t0 values(2);
+explain select * from t1 where 2 in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; Start temporary; End temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+select * from t1 where 2 in (select a from t0);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+set @@optimizer_switch='default,materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+select * from t1 where 2 in (select a from t0);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+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 subselect3 eq_ref unique_key unique_key 5 func 1
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 20
+2 DERIVED t0 ALL NULL NULL NULL NULL 11
+drop table t0, t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2));
+insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C;
+insert into t1 select * from t1 where kp1 < 20;
+create table t3 (a int);
+insert into t3 select A.a + 10*B.a from t0 A, t0 B;
+explain select * from t3 where a in (select kp1 from t1 where kp1<20);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using where; Using index
+create table t4 (pk int primary key);
+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
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR
+2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index
+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;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+set @@max_heap_table_size= 16384;
+explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
+1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
+1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
+1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (incremental, BNL join)
+flush status;
+select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+count(*)
+5000
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+set @save_max_heap_table_size=@@max_heap_table_size;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a int);
+insert into t2 values (1),(2);
+create table t3 ( a int , filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
+explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
+1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer (flat, BKA join)
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+select * from t3 where a in (select a from t2);
+a filler
+1 filler
+2 filler
+drop table t0, t2, t3;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+create table t1 (a date);
+insert into t1 values ('2008-01-01'),('2008-01-01'),('2008-02-01'),('2008-02-01');
+create table t2 (a int);
+insert into t2 values (1),(2);
+create table t3 (a char(10));
+insert into t3 select * from t1;
+insert into t3 values (1),(2);
+explain select * from t2 where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+explain select * from t2 where a 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 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+explain select * from t2 where a in (select a from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+explain select * from t1 where a in (select a from t3);
+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 t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+drop table t1, t2, t3;
+create table t1 (a decimal);
+insert into t1 values (1),(2);
+explain select * from t1 where a 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 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 as select * from t1;
+create table t3 (a int, b int, filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t1 A, t1 B, t1 C;
+explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer (flat, BKA join)
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+2 SUBQUERY A ALL NULL NULL NULL NULL 10
+2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+2 SUBQUERY A ALL NULL NULL NULL NULL 10
+2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+explain select straight_join * from t2 X, t2 Y
+where X.a in (select straight_join A.a from t1 A, t1 B);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+2 SUBQUERY A ALL NULL NULL NULL NULL 10
+2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+create table t0 (a int, b int);
+insert into t0 values(1,1);
+explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 system NULL NULL NULL NULL 1
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer (flat, BKA join)
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+create table t4 as select a as x, a as y from t1;
+explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 system NULL NULL NULL NULL 1
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; Using join buffer (flat, BKA join)
+2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
+drop table t0,t1,t2,t3,t4;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, filler char(100), key(a,b));
+insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B;
+create table t2 as select * from t1;
+explain select * from t2 where a in (select b from t1 where a=3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
+explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
+1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
+drop table t1,t2;
+create table t1 (a int, b int);
+insert into t1 select a,a from t0;
+create table t2 (a int, b int);
+insert into t2 select A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B;
+set @@optimizer_switch='firstmatch=off';
+explain select * from t1 where (a,b) 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 10
+1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
+set @save_optimizer_search_depth=@@optimizer_search_depth;
+set @@optimizer_search_depth=63;
+explain select * from t1 where (a,b) 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 10
+1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
+set @@optimizer_search_depth=@save_optimizer_search_depth;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+create table t0 (a decimal(4,2));
+insert into t0 values (10.24), (22.11);
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
+select * from t0 where a in (select a from t1);
+a
+10.24
+22.11
+drop table t0, t1;
+create table t0(a date);
+insert into t0 values ('2008-01-01'),('2008-02-02');
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
+select * from t0 where a in (select a from t1);
+a
+2008-01-01
+2008-02-02
+drop table t0, t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select a as a, a as b, a as c from t0 where a < 3;
+create table t2 as select a as a, a as b from t0 where a < 3;
+insert into t2 select * from t2;
+explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
+2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer (incremental, BNL join)
+drop table t0,t1,t2;
+
+BUG#37842: Assertion in DsMrr_impl::dsmrr_init, at handler.cc:4307
+
+CREATE TABLE t1 (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_key` int(11) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,9),(2,3),(3,8),(4,6),(5,9),(6,5),(7,5),(8,9),(9,1),(10,10);
+SELECT `pk` FROM t1 AS OUTR WHERE `int_key` = ALL (
+SELECT `int_key` FROM t1 AS INNR WHERE INNR . `pk` >= 9
+);
+pk
+DROP TABLE t1;
+
+BUG#40118 Crash when running Batched Key Access and requiring one match for each key
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, key(a));
+insert into t1 select * from t0;
+alter table t1 add b int not null, add filler char(200);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+select * from t0 where t0.a in (select t1.a from t1 where t1.b=0);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+set join_cache_level=@save_join_cache_level;
+drop table t0, t1;
+#
+# BUG#32665 Query with dependent subquery is too slow
+#
+create table t1 (
+idIndividual int primary key
+);
+insert into t1 values (1),(2);
+create table t2 (
+idContact int primary key,
+contactType int,
+idObj int
+);
+insert into t2 values (1,1,1),(2,2,2),(3,3,3);
+create table t3 (
+idAddress int primary key,
+idContact int,
+postalStripped varchar(100)
+);
+insert into t3 values (1,1, 'foo'), (2,2,'bar');
+The following must be converted to a semi-join:
+explain extended SELECT a.idIndividual FROM t1 a
+WHERE a.idIndividual IN
+( SELECT c.idObj FROM t3 cona
+INNER JOIN t2 c ON c.idContact=cona.idContact
+WHERE cona.postalStripped='T2H3B2'
+ );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
+1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using join buffer (flat, BKA join)
+Warnings:
+Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`c`.`idContact` = `test`.`cona`.`idContact`) and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`cona`.`postalStripped` = 'T2H3B2'))
+drop table t1,t2,t3;
+#
+# BUG#47367 Crash in Name_resolution_context::process_error
+#
+SET SESSION optimizer_switch = 'default,semijoin=off';
+CREATE TABLE t1 (f1 INTEGER);
+CREATE TABLE t2 LIKE t1;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+CALL p1;
+f1
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+CALL p1;
+f1
+DROP PROCEDURE p1;
+# Restore the original column list of table t2:
+ALTER TABLE t2 CHANGE COLUMN my_column f1 INT;
+SET SESSION optimizer_switch = 'semijoin=on';
+# Recreate procedure so that we eliminate any caching effects
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+CALL p1;
+f1
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+CALL p1;
+ERROR 42S22: Unknown column 'f1' in 'where clause'
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 50c0d14968a..8547a180d49 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -13,9 +13,9 @@ SELECT 1 FROM t1
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
ORDER BY count(*);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL a 5 NULL 2 Using index; Using temporary
+1 PRIMARY t1 index NULL a 5 NULL 2 Using where; Using index; Using temporary
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
-3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
# should not crash the next statement
SELECT 1 FROM t1
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
@@ -51,7 +51,7 @@ FROM t3 WHERE 1 = 0 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
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using index
-2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer
+2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
# should return 0 rows
SELECT
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
@@ -117,14 +117,14 @@ EXPLAIN
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
id select_type table type possible_keys key key_len ref rows Extra
x PRIMARY x x x x x x x x
-x DEPENDENT SUBQUERY x x x x x x x x
+x SUBQUERY x x x x x x x x
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
a b
EXPLAIN
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
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
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
a b
1 NULL
@@ -147,28 +147,28 @@ EXPLAIN
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
id select_type table type possible_keys key key_len ref rows Extra
x PRIMARY x x x x x x x x
-x DEPENDENT SUBQUERY x x x x x x x x
+x SUBQUERY x x x x x x x x
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
a b
EXPLAIN
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
id select_type table type possible_keys key key_len ref rows Extra
x PRIMARY x x x x x x x x
-x DEPENDENT SUBQUERY x x x x x x x x
+x SUBQUERY x x x x x x x x
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
c d
EXPLAIN
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
id select_type table type possible_keys key key_len ref rows Extra
x PRIMARY x x x x x x x x
-x DEPENDENT SUBQUERY x x x x x x x x
+x SUBQUERY x x x x x x x x
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
e f
EXPLAIN
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
id select_type table type possible_keys key key_len ref rows Extra
x PRIMARY x x x x x x x x
-x DEPENDENT SUBQUERY x x x x x x x x
+x SUBQUERY x x x x x x x x
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
c d
SELECT * FROM t1 WHERE ( a, b ) NOT IN
@@ -188,3 +188,298 @@ DROP TABLE t1, t2, t3, t4, t5;
#
# End of 5.1 tests.
#
+#
+# BUG#46743 "Azalea processing correlated, aggregate SELECT
+# subqueries incorrectly"
+#
+CREATE TABLE t1 (c int);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 (d int , KEY (d));
+INSERT INTO t2 VALUES (NULL),(NULL);
+0 rows in subquery
+SELECT 1 AS RESULT FROM t2,t1 WHERE d = c;
+RESULT
+base query
+SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 ;
+RESULT
+NULL
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 ;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
+Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1`
+first equivalent variant
+SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c ;
+RESULT
+NULL
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c;
+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 noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
+Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1` group by NULL
+second equivalent variant
+SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
+RESULT
+NULL
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
+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 noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
+Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1` group by NULL
+DROP TABLE t1,t2;
+#
+# BUG#45928 "Differing query results depending on MRR and
+# engine_condition_pushdown settings"
+#
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`time_nokey` time NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `varchar_key` (`varchar_key`)
+) AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (10,'00:00:00','i','i'),(11,'00:00:00','','');
+set @old_optimizer_switch = @@session.optimizer_switch,
+@old_optimizer_use_mrr = @@session.optimizer_use_mrr,
+@old_engine_condition_pushdown = @@session.engine_condition_pushdown;
+SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off';
+SET SESSION optimizer_use_mrr = 'force';
+SET SESSION engine_condition_pushdown = 1;
+SELECT `time_nokey` G1 FROM t1 WHERE ( `varchar_nokey` , `varchar_key` ) IN (
+SELECT `varchar_nokey` , `varchar_nokey` ) AND `varchar_key` >= 'c' HAVING G1 ORDER
+BY `pk` ;
+G1
+set @@session.optimizer_switch = @old_optimizer_switch,
+@@session.optimizer_use_mrr = @old_optimizer_use_mrr,
+@@session.engine_condition_pushdown = @old_engine_condition_pushdown;
+DROP TABLE t1;
+#
+# BUG#45863 "Assertion failed: (fixed == 0), function fix_fields(),
+# file item.cc, line 4448"
+#
+DROP TABLE IF EXISTS C, BB;
+CREATE TABLE C (
+varchar_nokey varchar(1) NOT NULL
+);
+INSERT INTO C VALUES
+('k'),('a'),(''),('u'),('e'),('v'),('i'),
+('t'),('u'),('f'),('u'),('m'),('j'),('f'),
+('v'),('j'),('g'),('e'),('h'),('z');
+CREATE TABLE BB (
+varchar_nokey varchar(1) NOT NULL
+);
+INSERT INTO BB VALUES ('i'),('t');
+SELECT varchar_nokey FROM C
+WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey
+FROM BB);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT varchar_nokey FROM C
+WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey, varchar_nokey
+FROM BB);
+ERROR 42S22: Unknown column 'OUTR' in 'IN/ALL/ANY subquery'
+DROP TABLE C,BB;
+#
+# During work with BUG#45863 I had problems with a query that was
+# optimized differently in regular and prepared mode.
+# Because there was a bug in one of the selected strategies, I became
+# aware of the problem. Adding an EXPLAIN query to catch this.
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1
+(EMPNUM CHAR(3) NOT NULL,
+EMPNAME CHAR(20),
+GRADE DECIMAL(4),
+CITY CHAR(15));
+CREATE TABLE t2
+(PNUM CHAR(3) NOT NULL,
+PNAME CHAR(20),
+PTYPE CHAR(6),
+BUDGET DECIMAL(9),
+CITY CHAR(15));
+CREATE TABLE t3
+(EMPNUM CHAR(3) NOT NULL,
+PNUM CHAR(3) NOT NULL,
+HOURS DECIMAL(5));
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET @old_join_cache_level = @@session.join_cache_level;
+SET SESSION optimizer_switch = 'firstmatch=on,loosescan=on,materialization=on,semijoin=on';
+SET SESSION join_cache_level = 1;
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
+1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+DEALLOCATE PREPARE stmt;
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
+1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+DEALLOCATE PREPARE stmt;
+DROP INDEX t1_IDX ON t1;
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+DEALLOCATE PREPARE stmt;
+SET SESSION optimizer_switch = @old_optimizer_switch;
+SET SESSION join_cache_level = @old_join_cache_level;
+DROP TABLE t1, t2, t3;
+#
+# BUG#45221 Query SELECT pk FROM C WHERE pk IN (SELECT int_key) failing
+#
+CREATE TABLE t1 (
+i1_key INT,
+i2 INT,
+i3 INT,
+KEY i1_index (i1_key)
+);
+INSERT INTO t1 VALUES (9,1,2), (9,2,1);
+CREATE TABLE t2 (
+pk INT NOT NULL,
+i1 INT,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (9,1);
+# Enable Index condition pushdown
+SELECT @old_icp:=@@engine_condition_pushdown;
+@old_icp:=@@engine_condition_pushdown
+#
+SET SESSION engine_condition_pushdown = 'ON';
+
+SELECT pk
+FROM t2
+WHERE
+pk IN (
+SELECT i1_key
+FROM t1
+WHERE t1.i2 < t1.i3 XOR t2.i1 > 1
+ORDER BY t1.i2 desc);
+pk
+9
+# Restore old value for Index condition pushdown
+SET SESSION engine_condition_pushdown=@old_icp;
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/subselect_cache.result b/mysql-test/r/subselect_cache.result
new file mode 100644
index 00000000000..7b9dc3c943f
--- /dev/null
+++ b/mysql-test/r/subselect_cache.result
@@ -0,0 +1,3312 @@
+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);
+create table t2 (c int, d int);
+insert into t2 values (2,3),(3,4),(5,6),(4,1);
+*
+* Test subquery as top item in different clauses
+*
+#single value subquery test (SELECT list)
+flush status;
+select a, (select d from t2 where b=c) from t1;
+a (select d from t2 where b=c)
+1 3
+3 1
+1 3
+3 1
+3 1
+4 6
+4 6
+5 NULL
+5 NULL
+4 6
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 7
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 31
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a, (select d from t2 where b=c) from t1;
+a (select d from t2 where b=c)
+1 3
+3 1
+1 3
+3 1
+3 1
+4 6
+4 6
+5 NULL
+5 NULL
+4 6
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 61
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (where)
+flush status;
+select a from t1 where (select d from t2 where b=c);
+a
+1
+3
+1
+3
+3
+4
+4
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 7
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 31
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a from t1 where (select d from t2 where b=c);
+a
+1
+3
+1
+3
+3
+4
+4
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 61
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (having)
+flush status;
+select a from t1 where a > 0 having (select d from t2 where b=c);
+a
+1
+3
+1
+3
+3
+4
+4
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 7
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 31
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a from t1 where a > 0 having (select d from t2 where b=c);
+a
+1
+3
+1
+3
+3
+4
+4
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 61
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (OUTER JOIN ON)
+flush status;
+select ta.a, tb.a from t1 ta join t1 tb on (select d from t2 where tb.b=c);
+a a
+1 1
+3 1
+1 1
+3 1
+3 1
+4 1
+4 1
+5 1
+5 1
+4 1
+1 3
+3 3
+1 3
+3 3
+3 3
+4 3
+4 3
+5 3
+5 3
+4 3
+1 1
+3 1
+1 1
+3 1
+3 1
+4 1
+4 1
+5 1
+5 1
+4 1
+1 3
+3 3
+1 3
+3 3
+3 3
+4 3
+4 3
+5 3
+5 3
+4 3
+1 3
+3 3
+1 3
+3 3
+3 3
+4 3
+4 3
+5 3
+5 3
+4 3
+1 4
+3 4
+1 4
+3 4
+3 4
+4 4
+4 4
+5 4
+5 4
+4 4
+1 4
+3 4
+1 4
+3 4
+3 4
+4 4
+4 4
+5 4
+5 4
+4 4
+1 4
+3 4
+1 4
+3 4
+3 4
+4 4
+4 4
+5 4
+5 4
+4 4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 7
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 442
+set optimizer_switch='subquery_cache=off';
+flush status;
+select ta.a, tb.a from t1 ta join t1 tb on (select d from t2 where tb.b=c);
+a a
+1 1
+3 1
+1 1
+3 1
+3 1
+4 1
+4 1
+5 1
+5 1
+4 1
+1 3
+3 3
+1 3
+3 3
+3 3
+4 3
+4 3
+5 3
+5 3
+4 3
+1 1
+3 1
+1 1
+3 1
+3 1
+4 1
+4 1
+5 1
+5 1
+4 1
+1 3
+3 3
+1 3
+3 3
+3 3
+4 3
+4 3
+5 3
+5 3
+4 3
+1 3
+3 3
+1 3
+3 3
+3 3
+4 3
+4 3
+5 3
+5 3
+4 3
+1 4
+3 4
+1 4
+3 4
+3 4
+4 4
+4 4
+5 4
+5 4
+4 4
+1 4
+3 4
+1 4
+3 4
+3 4
+4 4
+4 4
+5 4
+5 4
+4 4
+1 4
+3 4
+1 4
+3 4
+3 4
+4 4
+4 4
+5 4
+5 4
+4 4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 472
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (GROUP BY)
+flush status;
+select max(a) from t1 GROUP BY (select d from t2 where b=c);
+max(a)
+5
+3
+1
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 10
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 17
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 4
+Handler_read_rnd_next 36
+set optimizer_switch='subquery_cache=off';
+flush status;
+select max(a) from t1 GROUP BY (select d from t2 where b=c);
+max(a)
+5
+3
+1
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 10
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 4
+Handler_read_rnd_next 86
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (distinct GROUP BY)
+flush status;
+select distinct max(a) from t1 GROUP BY (select d from t2 where b=c);
+max(a)
+5
+3
+1
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 10
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 17
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 4
+Handler_read_rnd_next 41
+set optimizer_switch='subquery_cache=off';
+flush status;
+select distinct max(a) from t1 GROUP BY (select d from t2 where b=c);
+max(a)
+5
+3
+1
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 10
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 4
+Handler_read_rnd_next 91
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (ORDER BY)
+flush status;
+select a from t1 ORDER BY (select d from t2 where b=c);
+a
+5
+5
+3
+3
+3
+1
+1
+4
+4
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 7
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 31
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a from t1 ORDER BY (select d from t2 where b=c);
+a
+5
+5
+3
+3
+3
+1
+1
+4
+4
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 61
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (distinct ORDER BY)
+flush status;
+select distinct a from t1 ORDER BY (select d from t2 where b=c);
+a
+5
+3
+1
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 7
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 4
+Handler_read_rnd_next 37
+set optimizer_switch='subquery_cache=off';
+flush status;
+select distinct a from t1 ORDER BY (select d from t2 where b=c);
+a
+5
+3
+1
+4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 4
+Handler_read_rnd_next 67
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (LEFT JOIN ON)
+flush status;
+select ta.a, tb.a from t1 ta left join t1 tb on (select d from t2 where tb.b=c);
+a a
+1 1
+1 3
+1 1
+1 3
+1 3
+1 4
+1 4
+1 4
+3 1
+3 3
+3 1
+3 3
+3 3
+3 4
+3 4
+3 4
+1 1
+1 3
+1 1
+1 3
+1 3
+1 4
+1 4
+1 4
+3 1
+3 3
+3 1
+3 3
+3 3
+3 4
+3 4
+3 4
+3 1
+3 3
+3 1
+3 3
+3 3
+3 4
+3 4
+3 4
+4 1
+4 3
+4 1
+4 3
+4 3
+4 4
+4 4
+4 4
+4 1
+4 3
+4 1
+4 3
+4 3
+4 4
+4 4
+4 4
+5 1
+5 3
+5 1
+5 3
+5 3
+5 4
+5 4
+5 4
+5 1
+5 3
+5 1
+5 3
+5 3
+5 4
+5 4
+5 4
+4 1
+4 3
+4 1
+4 3
+4 3
+4 4
+4 4
+4 4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 106
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 70
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 141
+set optimizer_switch='subquery_cache=off';
+flush status;
+select ta.a, tb.a from t1 ta left join t1 tb on (select d from t2 where tb.b=c);
+a a
+1 1
+1 3
+1 1
+1 3
+1 3
+1 4
+1 4
+1 4
+3 1
+3 3
+3 1
+3 3
+3 3
+3 4
+3 4
+3 4
+1 1
+1 3
+1 1
+1 3
+1 3
+1 4
+1 4
+1 4
+3 1
+3 3
+3 1
+3 3
+3 3
+3 4
+3 4
+3 4
+3 1
+3 3
+3 1
+3 3
+3 3
+3 4
+3 4
+3 4
+4 1
+4 3
+4 1
+4 3
+4 3
+4 4
+4 4
+4 4
+4 1
+4 3
+4 1
+4 3
+4 3
+4 4
+4 4
+4 4
+5 1
+5 3
+5 1
+5 3
+5 3
+5 4
+5 4
+5 4
+5 1
+5 3
+5 1
+5 3
+5 3
+5 4
+5 4
+5 4
+4 1
+4 3
+4 1
+4 3
+4 3
+4 4
+4 4
+4 4
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 671
+set optimizer_switch='subquery_cache=on';
+#single value subquery test (PS)
+prepare stmt1 from 'select a, (select d from t2 where b=c) + 1 from t1';
+execute stmt1;
+a (select d from t2 where b=c) + 1
+1 4
+3 2
+1 4
+3 2
+3 2
+4 7
+4 7
+5 NULL
+5 NULL
+4 7
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+execute stmt1;
+a (select d from t2 where b=c) + 1
+1 4
+3 2
+1 4
+3 2
+3 2
+4 7
+4 7
+5 NULL
+5 NULL
+4 7
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 12
+Subquery_cache_miss 8
+deallocate prepare stmt1;
+#single value subquery test (SP)
+CREATE PROCEDURE p1() select a, (select d from t2 where b=c) + 1 from t1;
+call p1;
+a (select d from t2 where b=c) + 1
+1 4
+3 2
+1 4
+3 2
+3 2
+4 7
+4 7
+5 NULL
+5 NULL
+4 7
+call p1;
+a (select d from t2 where b=c) + 1
+1 4
+3 2
+1 4
+3 2
+3 2
+4 7
+4 7
+5 NULL
+5 NULL
+4 7
+drop procedure p1;
+#IN subquery test
+flush status;
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+select a, b , b in (select d from t2) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 4
+insert into t1 values (7,8),(9,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+7 8 0
+9 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 12
+Subquery_cache_miss 10
+insert into t2 values (8,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+a b SUBS
+1 2 NULL
+3 4 1
+1 2 NULL
+3 4 1
+3 4 1
+4 5 NULL
+4 5 NULL
+5 6 1
+5 6 1
+4 5 NULL
+7 8 NULL
+9 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 18
+Subquery_cache_miss 16
+# multicolumn NOT IN with NULLs
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (b, a) not in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 1
+3 4 0
+1 2 1
+3 4 0
+3 4 0
+4 5 1
+4 5 1
+5 6 0
+5 6 0
+4 5 1
+7 8 1
+9 NULL 1
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+set optimizer_switch='subquery_cache=on';
+select a, b, (b, a) not in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 1
+3 4 0
+1 2 1
+3 4 0
+3 4 0
+4 5 1
+4 5 1
+5 6 0
+5 6 0
+4 5 1
+7 8 1
+9 NULL 1
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 6
+# multicolumn NOT IN with NULLs (other order)
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (a, b) not in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 1
+3 4 1
+1 2 1
+3 4 1
+3 4 1
+4 5 1
+4 5 1
+5 6 1
+5 6 1
+4 5 1
+7 8 NULL
+9 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+set optimizer_switch='subquery_cache=on';
+select a, b, (a, b) not in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 1
+3 4 1
+1 2 1
+3 4 1
+3 4 1
+4 5 1
+4 5 1
+5 6 1
+5 6 1
+4 5 1
+7 8 NULL
+9 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 6
+# multicolumn IN with NULLs
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (b, a) in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+7 8 0
+9 NULL 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+set optimizer_switch='subquery_cache=on';
+select a, b, (b, a) in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+7 8 0
+9 NULL 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 6
+# multicolumn IN with NULLs (other order)
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (a, b) in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 0
+1 2 0
+3 4 0
+3 4 0
+4 5 0
+4 5 0
+5 6 0
+5 6 0
+4 5 0
+7 8 NULL
+9 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+set optimizer_switch='subquery_cache=on';
+select a, b, (a, b) in (select d, c from t2) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 0
+1 2 0
+3 4 0
+3 4 0
+4 5 0
+4 5 0
+5 6 0
+5 6 0
+4 5 0
+7 8 NULL
+9 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 6
+#IN subquery test (PS)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+prepare stmt1 from 'select a, b , b in (select d from t2) as SUBS from t1';
+execute stmt1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 12
+Subquery_cache_miss 10
+execute stmt1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 18
+Subquery_cache_miss 14
+insert into t1 values (7,8),(9,NULL);
+execute stmt1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL NULL
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 24
+Subquery_cache_miss 20
+execute stmt1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL NULL
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 30
+Subquery_cache_miss 26
+insert into t2 values (8,NULL);
+execute stmt1;
+a b SUBS
+1 2 NULL
+3 4 1
+1 2 NULL
+3 4 1
+3 4 1
+4 5 NULL
+4 5 NULL
+5 6 1
+5 6 1
+4 5 NULL
+9 NULL NULL
+7 8 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 36
+Subquery_cache_miss 32
+execute stmt1;
+a b SUBS
+1 2 NULL
+3 4 1
+1 2 NULL
+3 4 1
+3 4 1
+4 5 NULL
+4 5 NULL
+5 6 1
+5 6 1
+4 5 NULL
+9 NULL NULL
+7 8 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 42
+Subquery_cache_miss 38
+deallocate prepare stmt1;
+#IN subquery test (SP)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+CREATE PROCEDURE p1() select a, b , b in (select d from t2) as SUBS from t1;
+call p1();
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 48
+Subquery_cache_miss 42
+call p1();
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 54
+Subquery_cache_miss 46
+insert into t1 values (7,8),(9,NULL);
+call p1();
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL NULL
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 60
+Subquery_cache_miss 52
+call p1();
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL NULL
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 66
+Subquery_cache_miss 58
+insert into t2 values (8,NULL);
+call p1();
+a b SUBS
+1 2 NULL
+3 4 1
+1 2 NULL
+3 4 1
+3 4 1
+4 5 NULL
+4 5 NULL
+5 6 1
+5 6 1
+4 5 NULL
+9 NULL NULL
+7 8 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 72
+Subquery_cache_miss 64
+call p1();
+a b SUBS
+1 2 NULL
+3 4 1
+1 2 NULL
+3 4 1
+3 4 1
+4 5 NULL
+4 5 NULL
+5 6 1
+5 6 1
+4 5 NULL
+9 NULL NULL
+7 8 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 78
+Subquery_cache_miss 70
+drop procedure p1;
+# test of simple exists
+select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL 0
+7 8 0
+# test of prepared statement exists
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 84
+Subquery_cache_miss 76
+prepare stmt1 from 'select a, b , exists (select * from t2 where b=d) as SUBS from t1';
+execute stmt1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL 0
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 90
+Subquery_cache_miss 82
+execute stmt1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL 0
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 96
+Subquery_cache_miss 88
+deallocate prepare stmt1;
+# test of stored procedure exists
+CREATE PROCEDURE p1() select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+call p1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL 0
+7 8 0
+call p1;
+a b SUBS
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 1
+5 6 1
+4 5 0
+9 NULL 0
+7 8 0
+drop procedure p1;
+#several subqueries
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a, b , exists (select * from t2 where b=d) as SUBSE, b in (select d from t2) as SUBSI, (select d from t2 where b=c) SUBSR from t1;
+a b SUBSE SUBSI SUBSR
+1 2 0 NULL 3
+3 4 1 1 1
+1 2 0 NULL 3
+3 4 1 1 1
+3 4 1 1 1
+4 5 0 NULL 6
+4 5 0 NULL 6
+5 6 1 1 NULL
+5 6 1 1 NULL
+4 5 0 NULL 6
+9 NULL 0 NULL NULL
+7 8 0 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 11
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 145
+set optimizer_switch='subquery_cache=on';
+flush status;
+select a, b , exists (select * from t2 where b=d) as SUBSE, b in (select d from t2) as SUBSI, (select d from t2 where b=c) SUBSR from t1;
+a b SUBSE SUBSI SUBSR
+1 2 0 NULL 3
+3 4 1 1 1
+1 2 0 NULL 3
+3 4 1 1 1
+3 4 1 1 1
+4 5 0 NULL 6
+4 5 0 NULL 6
+5 6 1 1 NULL
+5 6 1 1 NULL
+4 5 0 NULL 6
+9 NULL 0 NULL NULL
+7 8 0 NULL NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 18
+Subquery_cache_miss 18
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 32
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 84
+#several subqueries (several levels)
+set optimizer_switch='subquery_cache=off';
+flush status;
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a, b, (select exists (select * from t2 where b=d) from t2 where b=c) as SUNS1 from t1;
+a b SUNS1
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 NULL
+5 6 NULL
+4 5 0
+9 NULL NULL
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 127
+set optimizer_switch='subquery_cache=on';
+flush status;
+select a, b, (select exists (select * from t2 where b=d) from t2 where b=c) as SUNS1 from t1;
+a b SUNS1
+1 2 0
+3 4 1
+1 2 0
+3 4 1
+3 4 1
+4 5 0
+4 5 0
+5 6 NULL
+5 6 NULL
+4 5 0
+9 NULL NULL
+7 8 0
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 6
+Subquery_cache_miss 10
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 13
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 69
+#clean up
+drop table t1,t2;
+test different types
+#int
+CREATE TABLE t1 ( a int, b int);
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+DROP TABLE t1;
+#char
+CREATE TABLE t1 ( a char(1), b char (1));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#decimal
+CREATE TABLE t1 ( a decimal(3,1), b decimal(3,1));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+a
+1.0
+3.0
+DROP TABLE t1;
+#date
+CREATE TABLE t1 ( a date, b date);
+INSERT INTO t1 VALUES('1000-01-01','1000-01-01'),('2000-02-01','2000-02-01'),('3000-03-03','3000-03-03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-01');
+a
+1000-01-01
+3000-03-03
+DROP TABLE t1;
+#datetime
+CREATE TABLE t1 ( a datetime, b datetime);
+INSERT INTO t1 VALUES('1000-01-01 01:01:01','1000-01-01 01:01:01'),('2000-02-02 02:02:02','2000-02-02 02:02:02'),('3000-03-03 03:03:03','3000-03-03 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+a
+1000-01-01 01:01:01
+3000-03-03 03:03:03
+DROP TABLE t1;
+#time
+CREATE TABLE t1 ( a time, b time);
+INSERT INTO t1 VALUES('01:01:01','01:01:01'),('02:02:02','02:02:02'),('03:03:03','03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '02:02:02');
+a
+01:01:01
+03:03:03
+DROP TABLE t1;
+#timestamp
+CREATE TABLE t1 ( a timestamp, b timestamp);
+INSERT INTO t1 VALUES('2000-02-02 01:01:01','2000-02-02 01:01:01'),('2000-02-02 02:02:02','2000-02-02 02:02:02'),('2000-02-02 03:03:03','2000-02-02 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+a
+2000-02-02 01:01:01
+2000-02-02 03:03:03
+DROP TABLE t1;
+#bit
+CREATE TABLE t1 ( a bit(20), b bit(20));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a+0 FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+a+0
+1
+3
+DROP TABLE t1;
+#enum
+CREATE TABLE t1 ( a enum('1','2','3'), b enum('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#set
+CREATE TABLE t1 ( a set('1','2','3'), b set('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#blob
+CREATE TABLE t1 ( a blob, b blob);
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#geometry
+CREATE TABLE t1 ( a geometry, b geometry);
+INSERT INTO t1 VALUES(POINT(1,1),POINT(1,1)),(POINT(2,2),POINT(2,2)),(POINT(3,3),POINT(3,3));
+SELECT astext(a) FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = POINT(2,2));
+astext(a)
+POINT(1 1)
+POINT(3 3)
+DROP TABLE t1;
+#uncacheable queries test (random and side effect)
+flush status;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+select a, a in (select a from t1) from t1 as ext;
+a a in (select a from t1)
+2 1
+4 1
+1 1
+3 1
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 4
+select a, a in (select a from t1 where -1 < rand()) from t1 as ext;
+a a in (select a from t1 where -1 < rand())
+2 1
+4 1
+1 1
+3 1
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 4
+select a, a in (select a from t1 where -1 < benchmark(a,100)) from t1 as ext;
+a a in (select a from t1 where -1 < benchmark(a,100))
+2 1
+4 1
+1 1
+3 1
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 4
+drop table t1;
+#test of sql_big_tables switch and outer table reference in subquery with grouping
+set option sql_big_tables=1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
+INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3);
+SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer;
+(SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1)
+1
+2
+3
+4
+5
+6
+drop table t1;
+set option sql_big_tables=0;
+#test of function reference to outer query
+set local group_concat_max_len=400;
+create table t2 (a int, b int);
+insert into t2 values (1,1), (2,2);
+select b x, (select group_concat(x) from t2) from t2;
+x (select group_concat(x) from t2)
+1 1,1
+2 2,2
+drop table t2;
+set local group_concat_max_len=default;
+#aggregate functions
+CREATE TABLE t1 (a int, b INT);
+CREATE TABLE t2 (c int, d INT);
+insert into t1 values (2,1), (3,1), (2,4), (3,4), (10,2), (20,2), (2,5),
+(3,5), (100,3), (200,3), (10,6), (20,6), (20,7), (100,8), (200,8);
+insert into t2 values (1,1),(3,3),(20,20);
+aggregate function as parameter of subquery
+set optimizer_switch='subquery_cache=off';
+flush status;
+select max(a), (select max(a) from t2 where max(a)=c) from t1 group by b;
+max(a) (select max(a) from t2 where max(a)=c)
+3 3
+20 20
+200 NULL
+3 3
+3 3
+20 20
+20 20
+200 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 15
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 8
+Handler_read_rnd_next 57
+set optimizer_switch='subquery_cache=on';
+flush status;
+select max(a), (select max(a) from t2 where max(a)=c) from t1 group by b;
+max(a) (select max(a) from t2 where max(a)=c)
+3 3
+20 20
+200 NULL
+3 3
+3 3
+20 20
+20 20
+200 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 5
+Subquery_cache_miss 3
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 21
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 8
+Handler_read_rnd_next 37
+argument of aggregate function as parameter of subquery (illegal use)
+set optimizer_switch='subquery_cache=off';
+flush status;
+select max(a), (select a from t2 where a=c) from t1 group by b;
+max(a) (select a from t2 where a=c)
+3 NULL
+20 NULL
+200 NULL
+3 NULL
+3 NULL
+20 NULL
+20 20
+200 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 15
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 8
+Handler_read_rnd_next 57
+set optimizer_switch='subquery_cache=on';
+flush status;
+select max(a), (select a from t2 where a=c) from t1 group by b;
+max(a) (select a from t2 where a=c)
+3 NULL
+20 NULL
+200 NULL
+3 NULL
+3 NULL
+20 NULL
+20 20
+200 NULL
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 4
+Subquery_cache_miss 4
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 22
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 8
+Handler_read_rnd_next 41
+drop table t1,t2;
+#test of flattening subquery optimisations and cache
+create table t0 (a int);
+insert into t0 values (9),(8),(7),(6),(5),(4),(3),(2),(1),(0);
+create table t1(a int, b int);
+insert into t1 values
+(0,0),(1,1),(2,2),(0,0),(1,1),(2,2),(0,0),(1,1),(2,2),(0,0),(1,1),(2,2),(0,0),(1,1),(2,2);
+create table t2 (pk int, a int, primary key(pk));
+insert into t2 select a,a from t0;
+set optimizer_switch='default,semijoin=on,materialization=on,subquery_cache=on';
+flush status;
+select * from t1 where a in (select pk from t2);
+a b
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 15
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 16
+alter table t2 drop primary key;
+set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=off';
+explain select * from t1 where a in (select pk from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 15 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+flush status;
+select * from t1 where a in (select pk from t2);
+a b
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 0
+Subquery_cache_miss 0
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 151
+set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=on';
+explain select * from t1 where a in (select pk from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 15 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+flush status;
+select * from t1 where a in (select pk from t2);
+a b
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 12
+Subquery_cache_miss 3
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 15
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 43
+set optimizer_switch='default,semijoin=off,materialization=on,subquery_cache=on';
+explain select * from t1 where a in (select pk from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 15 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
+flush status;
+select * from t1 where a in (select pk from t2);
+a b
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+0 0
+1 1
+2 2
+show status like "subquery_cache%";
+Variable_name Value
+Subquery_cache_hit 12
+Subquery_cache_miss 3
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 18
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 27
+drop table t0,t1,t2;
+set optimizer_switch='default';
+#launchpad BUG#608834
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,7,8,'01:27:35','v','v');
+INSERT INTO `t2` VALUES (11,1,9,'19:48:31','r','r');
+INSERT INTO `t2` VALUES (12,5,9,'00:00:00','a','a');
+INSERT INTO `t2` VALUES (13,3,186,'19:53:05','m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,'19:18:56','y','y');
+INSERT INTO `t2` VALUES (15,92,2,'10:55:12','j','j');
+INSERT INTO `t2` VALUES (16,7,3,'00:25:00','d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'12:35:47','z','z');
+INSERT INTO `t2` VALUES (18,3,133,'19:53:03','e','e');
+INSERT INTO `t2` VALUES (19,5,1,'17:53:30','h','h');
+INSERT INTO `t2` VALUES (20,1,8,'11:35:49','b','b');
+INSERT INTO `t2` VALUES (21,2,5,NULL,'s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'06:01:40','e','e');
+INSERT INTO `t2` VALUES (23,1,8,'05:45:11','j','j');
+INSERT INTO `t2` VALUES (24,0,6,'00:00:00','e','e');
+INSERT INTO `t2` VALUES (25,210,51,'00:00:00','f','f');
+INSERT INTO `t2` VALUES (26,8,4,'06:11:01','v','v');
+INSERT INTO `t2` VALUES (27,7,7,'13:02:46','x','x');
+INSERT INTO `t2` VALUES (28,5,6,'21:44:25','m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'22:43:58','c','c');
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,'11:28:45','w','w');
+INSERT INTO `t1` VALUES (2,7,9,'20:25:14','m','m');
+INSERT INTO `t1` VALUES (3,9,3,'13:47:24','m','m');
+INSERT INTO `t1` VALUES (4,7,9,'19:24:11','k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'15:59:13','r','r');
+INSERT INTO `t1` VALUES (6,2,9,'00:00:00','t','t');
+INSERT INTO `t1` VALUES (7,6,3,'15:15:04','j','j');
+INSERT INTO `t1` VALUES (8,8,8,'11:32:06','u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'18:32:33','h','h');
+INSERT INTO `t1` VALUES (10,5,53,'15:19:25','o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,'19:03:19',NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'00:39:46','k','k');
+INSERT INTO `t1` VALUES (13,188,166,NULL,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,'00:00:00','n','n');
+INSERT INTO `t1` VALUES (15,1,0,'13:12:11','t','t');
+INSERT INTO `t1` VALUES (16,1,1,'04:56:48','c','c');
+INSERT INTO `t1` VALUES (17,0,9,'19:56:05','m','m');
+INSERT INTO `t1` VALUES (18,9,5,'19:35:19','y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'05:03:03','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'18:38:59','d','d');
+set @@optimizer_switch='subquery_cache=off';
+/* cache is off */ SELECT (
+SELECT 4
+FROM DUAL ) AS field1 , SUM( DISTINCT table1 . `pk` ) AS field2 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_nokey` ) AS SUBQUERY2_field1
+FROM ( t1 AS SUBQUERY2_t1 INNER JOIN t1 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `pk` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` <= table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_int_nokey` < table1 . `pk` ) AS field3 , table1 . `col_time_key` AS field4 , table1 . `col_int_key` AS field5 , CONCAT ( table2 . `col_varchar_nokey` , table1 . `col_varchar_key` ) AS field6
+FROM ( t1 AS table1 INNER JOIN ( ( t1 AS table2 LEFT JOIN t2 AS table3 ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_nokey` ) )
+WHERE ( table2 . `col_varchar_nokey` NOT IN (
+SELECT 'd' UNION
+SELECT 'u' ) ) OR table3 . `col_varchar_nokey` <= table1 . `col_varchar_key`
+GROUP BY field1, field3, field4, field5, field6
+ORDER BY table1 . `col_int_key` , field1, field2, field3, field4, field5, field6
+;
+field1 field2 field3 field4 field5 field6
+4 5 9 15:59:13 NULL cr
+4 5 9 15:59:13 NULL dr
+4 5 9 15:59:13 NULL er
+4 5 9 15:59:13 NULL fr
+4 5 9 15:59:13 NULL hr
+4 5 9 15:59:13 NULL jr
+4 5 9 15:59:13 NULL mr
+4 5 9 15:59:13 NULL rr
+4 5 9 15:59:13 NULL yr
+4 11 9 19:03:19 0 NULL
+4 15 9 13:12:11 0 ct
+4 15 9 13:12:11 0 dt
+4 15 9 13:12:11 0 et
+4 15 9 13:12:11 0 ft
+4 15 9 13:12:11 0 ht
+4 15 9 13:12:11 0 jt
+4 15 9 13:12:11 0 mt
+4 15 9 13:12:11 0 rt
+4 15 9 13:12:11 0 yt
+4 16 9 04:56:48 1 cc
+4 16 9 04:56:48 1 ec
+4 16 9 04:56:48 1 fc
+4 16 9 04:56:48 1 hc
+4 16 9 04:56:48 1 jc
+4 16 9 04:56:48 1 mc
+4 16 9 04:56:48 1 rc
+4 16 9 04:56:48 1 yc
+4 1 9 11:28:45 2 cw
+4 1 9 11:28:45 2 dw
+4 1 9 11:28:45 2 ew
+4 1 9 11:28:45 2 fw
+4 1 9 11:28:45 2 hw
+4 1 9 11:28:45 2 jw
+4 1 9 11:28:45 2 mw
+4 1 9 11:28:45 2 rw
+4 1 9 11:28:45 2 yw
+4 20 9 18:38:59 2 cd
+4 20 9 18:38:59 2 dd
+4 20 9 18:38:59 2 ed
+4 20 9 18:38:59 2 fd
+4 20 9 18:38:59 2 hd
+4 20 9 18:38:59 2 jd
+4 20 9 18:38:59 2 md
+4 20 9 18:38:59 2 rd
+4 20 9 18:38:59 2 yd
+4 3 9 13:47:24 3 cm
+4 3 9 13:47:24 3 dm
+4 3 9 13:47:24 3 em
+4 3 9 13:47:24 3 fm
+4 3 9 13:47:24 3 hm
+4 3 9 13:47:24 3 jm
+4 3 9 13:47:24 3 mm
+4 3 9 13:47:24 3 rm
+4 3 9 13:47:24 3 ym
+4 7 9 15:15:04 3 cj
+4 7 9 15:15:04 3 dj
+4 7 9 15:15:04 3 ej
+4 7 9 15:15:04 3 fj
+4 7 9 15:15:04 3 hj
+4 7 9 15:15:04 3 jj
+4 7 9 15:15:04 3 mj
+4 7 9 15:15:04 3 rj
+4 7 9 15:15:04 3 yj
+4 14 9 00:00:00 3 cn
+4 14 9 00:00:00 3 dn
+4 14 9 00:00:00 3 en
+4 14 9 00:00:00 3 fn
+4 14 9 00:00:00 3 hn
+4 14 9 00:00:00 3 jn
+4 14 9 00:00:00 3 mn
+4 14 9 00:00:00 3 rn
+4 14 9 00:00:00 3 yn
+4 12 9 00:39:46 5 ck
+4 12 9 00:39:46 5 dk
+4 12 9 00:39:46 5 ek
+4 12 9 00:39:46 5 fk
+4 12 9 00:39:46 5 hk
+4 12 9 00:39:46 5 jk
+4 12 9 00:39:46 5 mk
+4 12 9 00:39:46 5 rk
+4 12 9 00:39:46 5 yk
+4 18 9 19:35:19 5 cy
+4 18 9 19:35:19 5 dy
+4 18 9 19:35:19 5 ey
+4 18 9 19:35:19 5 fy
+4 18 9 19:35:19 5 hy
+4 18 9 19:35:19 5 jy
+4 18 9 19:35:19 5 my
+4 18 9 19:35:19 5 ry
+4 18 9 19:35:19 5 yy
+4 19 9 05:03:03 6 cf
+4 19 9 05:03:03 6 df
+4 19 9 05:03:03 6 ef
+4 19 9 05:03:03 6 ff
+4 19 9 05:03:03 6 hf
+4 19 9 05:03:03 6 jf
+4 19 9 05:03:03 6 mf
+4 19 9 05:03:03 6 rf
+4 19 9 05:03:03 6 yf
+4 8 9 11:32:06 8 cu
+4 8 9 11:32:06 8 du
+4 8 9 11:32:06 8 eu
+4 8 9 11:32:06 8 fu
+4 8 9 11:32:06 8 hu
+4 8 9 11:32:06 8 ju
+4 8 9 11:32:06 8 mu
+4 8 9 11:32:06 8 ru
+4 8 9 11:32:06 8 yu
+4 9 8 18:32:33 8 ch
+4 9 8 18:32:33 8 dh
+4 9 8 18:32:33 8 eh
+4 9 8 18:32:33 8 fh
+4 9 8 18:32:33 8 hh
+4 9 8 18:32:33 8 jh
+4 9 8 18:32:33 8 mh
+4 9 8 18:32:33 8 rh
+4 9 8 18:32:33 8 yh
+4 2 9 20:25:14 9 cm
+4 2 9 20:25:14 9 dm
+4 2 9 20:25:14 9 em
+4 2 9 20:25:14 9 fm
+4 2 9 20:25:14 9 hm
+4 2 9 20:25:14 9 jm
+4 2 9 20:25:14 9 mm
+4 2 9 20:25:14 9 rm
+4 2 9 20:25:14 9 ym
+4 4 9 19:24:11 9 ck
+4 4 9 19:24:11 9 dk
+4 4 9 19:24:11 9 ek
+4 4 9 19:24:11 9 fk
+4 4 9 19:24:11 9 hk
+4 4 9 19:24:11 9 jk
+4 4 9 19:24:11 9 mk
+4 4 9 19:24:11 9 rk
+4 4 9 19:24:11 9 yk
+4 6 9 00:00:00 9 ct
+4 6 9 00:00:00 9 dt
+4 6 9 00:00:00 9 et
+4 6 9 00:00:00 9 ft
+4 6 9 00:00:00 9 ht
+4 6 9 00:00:00 9 jt
+4 6 9 00:00:00 9 mt
+4 6 9 00:00:00 9 rt
+4 6 9 00:00:00 9 yt
+4 17 9 19:56:05 9 cm
+4 17 9 19:56:05 9 dm
+4 17 9 19:56:05 9 em
+4 17 9 19:56:05 9 fm
+4 17 9 19:56:05 9 hm
+4 17 9 19:56:05 9 jm
+4 17 9 19:56:05 9 mm
+4 17 9 19:56:05 9 rm
+4 17 9 19:56:05 9 ym
+4 10 9 15:19:25 53 co
+4 10 9 15:19:25 53 do
+4 10 9 15:19:25 53 eo
+4 10 9 15:19:25 53 fo
+4 10 9 15:19:25 53 ho
+4 10 9 15:19:25 53 jo
+4 10 9 15:19:25 53 mo
+4 10 9 15:19:25 53 ro
+4 10 9 15:19:25 53 yo
+4 13 9 NULL 166 ce
+4 13 9 NULL 166 de
+4 13 9 NULL 166 ee
+4 13 9 NULL 166 fe
+4 13 9 NULL 166 he
+4 13 9 NULL 166 je
+4 13 9 NULL 166 me
+4 13 9 NULL 166 re
+4 13 9 NULL 166 ye
+set @@optimizer_switch='subquery_cache=on';
+/* cache is on */ SELECT (
+SELECT 4
+FROM DUAL ) AS field1 , SUM( DISTINCT table1 . `pk` ) AS field2 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_nokey` ) AS SUBQUERY2_field1
+FROM ( t1 AS SUBQUERY2_t1 INNER JOIN t1 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `pk` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` <= table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_int_nokey` < table1 . `pk` ) AS field3 , table1 . `col_time_key` AS field4 , table1 . `col_int_key` AS field5 , CONCAT ( table2 . `col_varchar_nokey` , table1 . `col_varchar_key` ) AS field6
+FROM ( t1 AS table1 INNER JOIN ( ( t1 AS table2 LEFT JOIN t2 AS table3 ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_nokey` ) )
+WHERE ( table2 . `col_varchar_nokey` NOT IN (
+SELECT 'd' UNION
+SELECT 'u' ) ) OR table3 . `col_varchar_nokey` <= table1 . `col_varchar_key`
+GROUP BY field1, field3, field4, field5, field6
+ORDER BY table1 . `col_int_key` , field1, field2, field3, field4, field5, field6
+;
+field1 field2 field3 field4 field5 field6
+4 5 9 15:59:13 NULL cr
+4 5 9 15:59:13 NULL dr
+4 5 9 15:59:13 NULL er
+4 5 9 15:59:13 NULL fr
+4 5 9 15:59:13 NULL hr
+4 5 9 15:59:13 NULL jr
+4 5 9 15:59:13 NULL mr
+4 5 9 15:59:13 NULL rr
+4 5 9 15:59:13 NULL yr
+4 11 9 19:03:19 0 NULL
+4 15 9 13:12:11 0 ct
+4 15 9 13:12:11 0 dt
+4 15 9 13:12:11 0 et
+4 15 9 13:12:11 0 ft
+4 15 9 13:12:11 0 ht
+4 15 9 13:12:11 0 jt
+4 15 9 13:12:11 0 mt
+4 15 9 13:12:11 0 rt
+4 15 9 13:12:11 0 yt
+4 16 9 04:56:48 1 cc
+4 16 9 04:56:48 1 ec
+4 16 9 04:56:48 1 fc
+4 16 9 04:56:48 1 hc
+4 16 9 04:56:48 1 jc
+4 16 9 04:56:48 1 mc
+4 16 9 04:56:48 1 rc
+4 16 9 04:56:48 1 yc
+4 1 9 11:28:45 2 cw
+4 1 9 11:28:45 2 dw
+4 1 9 11:28:45 2 ew
+4 1 9 11:28:45 2 fw
+4 1 9 11:28:45 2 hw
+4 1 9 11:28:45 2 jw
+4 1 9 11:28:45 2 mw
+4 1 9 11:28:45 2 rw
+4 1 9 11:28:45 2 yw
+4 20 9 18:38:59 2 cd
+4 20 9 18:38:59 2 dd
+4 20 9 18:38:59 2 ed
+4 20 9 18:38:59 2 fd
+4 20 9 18:38:59 2 hd
+4 20 9 18:38:59 2 jd
+4 20 9 18:38:59 2 md
+4 20 9 18:38:59 2 rd
+4 20 9 18:38:59 2 yd
+4 3 9 13:47:24 3 cm
+4 3 9 13:47:24 3 dm
+4 3 9 13:47:24 3 em
+4 3 9 13:47:24 3 fm
+4 3 9 13:47:24 3 hm
+4 3 9 13:47:24 3 jm
+4 3 9 13:47:24 3 mm
+4 3 9 13:47:24 3 rm
+4 3 9 13:47:24 3 ym
+4 7 9 15:15:04 3 cj
+4 7 9 15:15:04 3 dj
+4 7 9 15:15:04 3 ej
+4 7 9 15:15:04 3 fj
+4 7 9 15:15:04 3 hj
+4 7 9 15:15:04 3 jj
+4 7 9 15:15:04 3 mj
+4 7 9 15:15:04 3 rj
+4 7 9 15:15:04 3 yj
+4 14 9 00:00:00 3 cn
+4 14 9 00:00:00 3 dn
+4 14 9 00:00:00 3 en
+4 14 9 00:00:00 3 fn
+4 14 9 00:00:00 3 hn
+4 14 9 00:00:00 3 jn
+4 14 9 00:00:00 3 mn
+4 14 9 00:00:00 3 rn
+4 14 9 00:00:00 3 yn
+4 12 9 00:39:46 5 ck
+4 12 9 00:39:46 5 dk
+4 12 9 00:39:46 5 ek
+4 12 9 00:39:46 5 fk
+4 12 9 00:39:46 5 hk
+4 12 9 00:39:46 5 jk
+4 12 9 00:39:46 5 mk
+4 12 9 00:39:46 5 rk
+4 12 9 00:39:46 5 yk
+4 18 9 19:35:19 5 cy
+4 18 9 19:35:19 5 dy
+4 18 9 19:35:19 5 ey
+4 18 9 19:35:19 5 fy
+4 18 9 19:35:19 5 hy
+4 18 9 19:35:19 5 jy
+4 18 9 19:35:19 5 my
+4 18 9 19:35:19 5 ry
+4 18 9 19:35:19 5 yy
+4 19 9 05:03:03 6 cf
+4 19 9 05:03:03 6 df
+4 19 9 05:03:03 6 ef
+4 19 9 05:03:03 6 ff
+4 19 9 05:03:03 6 hf
+4 19 9 05:03:03 6 jf
+4 19 9 05:03:03 6 mf
+4 19 9 05:03:03 6 rf
+4 19 9 05:03:03 6 yf
+4 8 9 11:32:06 8 cu
+4 8 9 11:32:06 8 du
+4 8 9 11:32:06 8 eu
+4 8 9 11:32:06 8 fu
+4 8 9 11:32:06 8 hu
+4 8 9 11:32:06 8 ju
+4 8 9 11:32:06 8 mu
+4 8 9 11:32:06 8 ru
+4 8 9 11:32:06 8 yu
+4 9 8 18:32:33 8 ch
+4 9 8 18:32:33 8 dh
+4 9 8 18:32:33 8 eh
+4 9 8 18:32:33 8 fh
+4 9 8 18:32:33 8 hh
+4 9 8 18:32:33 8 jh
+4 9 8 18:32:33 8 mh
+4 9 8 18:32:33 8 rh
+4 9 8 18:32:33 8 yh
+4 2 9 20:25:14 9 cm
+4 2 9 20:25:14 9 dm
+4 2 9 20:25:14 9 em
+4 2 9 20:25:14 9 fm
+4 2 9 20:25:14 9 hm
+4 2 9 20:25:14 9 jm
+4 2 9 20:25:14 9 mm
+4 2 9 20:25:14 9 rm
+4 2 9 20:25:14 9 ym
+4 4 9 19:24:11 9 ck
+4 4 9 19:24:11 9 dk
+4 4 9 19:24:11 9 ek
+4 4 9 19:24:11 9 fk
+4 4 9 19:24:11 9 hk
+4 4 9 19:24:11 9 jk
+4 4 9 19:24:11 9 mk
+4 4 9 19:24:11 9 rk
+4 4 9 19:24:11 9 yk
+4 6 9 00:00:00 9 ct
+4 6 9 00:00:00 9 dt
+4 6 9 00:00:00 9 et
+4 6 9 00:00:00 9 ft
+4 6 9 00:00:00 9 ht
+4 6 9 00:00:00 9 jt
+4 6 9 00:00:00 9 mt
+4 6 9 00:00:00 9 rt
+4 6 9 00:00:00 9 yt
+4 17 9 19:56:05 9 cm
+4 17 9 19:56:05 9 dm
+4 17 9 19:56:05 9 em
+4 17 9 19:56:05 9 fm
+4 17 9 19:56:05 9 hm
+4 17 9 19:56:05 9 jm
+4 17 9 19:56:05 9 mm
+4 17 9 19:56:05 9 rm
+4 17 9 19:56:05 9 ym
+4 10 9 15:19:25 53 co
+4 10 9 15:19:25 53 do
+4 10 9 15:19:25 53 eo
+4 10 9 15:19:25 53 fo
+4 10 9 15:19:25 53 ho
+4 10 9 15:19:25 53 jo
+4 10 9 15:19:25 53 mo
+4 10 9 15:19:25 53 ro
+4 10 9 15:19:25 53 yo
+4 13 9 NULL 166 ce
+4 13 9 NULL 166 de
+4 13 9 NULL 166 ee
+4 13 9 NULL 166 fe
+4 13 9 NULL 166 he
+4 13 9 NULL 166 je
+4 13 9 NULL 166 me
+4 13 9 NULL 166 re
+4 13 9 NULL 166 ye
+drop table t1,t2;
+set @@optimizer_switch= default;
+#launchpad BUG#609045
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,NULL,NULL,'11:28:45','11:28:45','2004-10-11 18:13:16','2004-10-11 18:13:16','w','w');
+INSERT INTO `t1` VALUES (2,7,9,'2001-09-19','2001-09-19','20:25:14','20:25:14',NULL,NULL,'m','m');
+INSERT INTO `t1` VALUES (3,9,3,'2004-09-12','2004-09-12','13:47:24','13:47:24','1900-01-01 00:00:00','1900-01-01 00:00:00','m','m');
+INSERT INTO `t1` VALUES (4,7,9,NULL,NULL,'19:24:11','19:24:11','2009-07-25 00:00:00','2009-07-25 00:00:00','k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'2002-07-19','2002-07-19','15:59:13','15:59:13',NULL,NULL,'r','r');
+INSERT INTO `t1` VALUES (6,2,9,'2002-12-16','2002-12-16','00:00:00','00:00:00','2008-07-27 00:00:00','2008-07-27 00:00:00','t','t');
+INSERT INTO `t1` VALUES (7,6,3,'2006-02-08','2006-02-08','15:15:04','15:15:04','2002-11-13 16:37:31','2002-11-13 16:37:31','j','j');
+INSERT INTO `t1` VALUES (8,8,8,'2006-08-28','2006-08-28','11:32:06','11:32:06','1900-01-01 00:00:00','1900-01-01 00:00:00','u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'2001-04-14','2001-04-14','18:32:33','18:32:33','2003-12-10 00:00:00','2003-12-10 00:00:00','h','h');
+INSERT INTO `t1` VALUES (10,5,53,'2000-01-05','2000-01-05','15:19:25','15:19:25','2001-12-21 22:38:22','2001-12-21 22:38:22','o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,'2003-12-06','2003-12-06','19:03:19','19:03:19','2008-12-13 23:16:44','2008-12-13 23:16:44',NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'1900-01-01','1900-01-01','00:39:46','00:39:46','2005-08-15 12:39:41','2005-08-15 12:39:41','k','k');
+INSERT INTO `t1` VALUES (13,188,166,'2002-11-27','2002-11-27',NULL,NULL,NULL,NULL,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,NULL,NULL,'00:00:00','00:00:00','2006-09-11 12:06:14','2006-09-11 12:06:14','n','n');
+INSERT INTO `t1` VALUES (15,1,0,'2003-05-27','2003-05-27','13:12:11','13:12:11','2007-12-15 12:39:34','2007-12-15 12:39:34','t','t');
+INSERT INTO `t1` VALUES (16,1,1,'2005-05-03','2005-05-03','04:56:48','04:56:48','2005-08-09 00:00:00','2005-08-09 00:00:00','c','c');
+INSERT INTO `t1` VALUES (17,0,9,'2001-04-18','2001-04-18','19:56:05','19:56:05','2001-09-02 22:50:02','2001-09-02 22:50:02','m','m');
+INSERT INTO `t1` VALUES (18,9,5,'2005-12-27','2005-12-27','19:35:19','19:35:19','2005-12-16 22:58:11','2005-12-16 22:58:11','y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'2004-08-20','2004-08-20','05:03:03','05:03:03','2007-04-19 00:19:53','2007-04-19 00:19:53','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'1900-01-01','1900-01-01','18:38:59','18:38:59','1900-01-01 00:00:00','1900-01-01 00:00:00','d','d');
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+INSERT INTO `t2` VALUES (10,7,8,NULL,NULL,'01:27:35','01:27:35','2002-02-26 06:14:37','2002-02-26 06:14:37','v','v');
+INSERT INTO `t2` VALUES (11,1,9,'2006-06-14','2006-06-14','19:48:31','19:48:31','1900-01-01 00:00:00','1900-01-01 00:00:00','r','r');
+INSERT INTO `t2` VALUES (12,5,9,'2002-09-12','2002-09-12','00:00:00','00:00:00','2006-12-03 09:37:26','2006-12-03 09:37:26','a','a');
+INSERT INTO `t2` VALUES (13,3,186,'2005-02-15','2005-02-15','19:53:05','19:53:05','2008-05-26 12:27:10','2008-05-26 12:27:10','m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,NULL,NULL,'19:18:56','19:18:56','2004-12-14 16:37:30','2004-12-14 16:37:30','y','y');
+INSERT INTO `t2` VALUES (15,92,2,'2008-11-04','2008-11-04','10:55:12','10:55:12','2003-02-11 21:19:41','2003-02-11 21:19:41','j','j');
+INSERT INTO `t2` VALUES (16,7,3,'2004-09-04','2004-09-04','00:25:00','00:25:00','2009-10-18 02:27:49','2009-10-18 02:27:49','d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'2006-06-05','2006-06-05','12:35:47','12:35:47','2000-09-26 07:45:57','2000-09-26 07:45:57','z','z');
+INSERT INTO `t2` VALUES (18,3,133,'1900-01-01','1900-01-01','19:53:03','19:53:03',NULL,NULL,'e','e');
+INSERT INTO `t2` VALUES (19,5,1,'1900-01-01','1900-01-01','17:53:30','17:53:30','2005-11-10 12:40:29','2005-11-10 12:40:29','h','h');
+INSERT INTO `t2` VALUES (20,1,8,'1900-01-01','1900-01-01','11:35:49','11:35:49','2009-04-25 00:00:00','2009-04-25 00:00:00','b','b');
+INSERT INTO `t2` VALUES (21,2,5,'2005-01-13','2005-01-13',NULL,NULL,'2002-11-27 00:00:00','2002-11-27 00:00:00','s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'2006-05-21','2006-05-21','06:01:40','06:01:40','2004-01-26 20:32:32','2004-01-26 20:32:32','e','e');
+INSERT INTO `t2` VALUES (23,1,8,'2003-09-08','2003-09-08','05:45:11','05:45:11','2007-10-26 11:41:40','2007-10-26 11:41:40','j','j');
+INSERT INTO `t2` VALUES (24,0,6,'2006-12-23','2006-12-23','00:00:00','00:00:00','2005-10-07 00:00:00','2005-10-07 00:00:00','e','e');
+INSERT INTO `t2` VALUES (25,210,51,'2006-10-15','2006-10-15','00:00:00','00:00:00','2000-07-15 05:00:34','2000-07-15 05:00:34','f','f');
+INSERT INTO `t2` VALUES (26,8,4,'2005-04-06','2005-04-06','06:11:01','06:11:01','2000-04-03 16:33:32','2000-04-03 16:33:32','v','v');
+INSERT INTO `t2` VALUES (27,7,7,'2008-04-07','2008-04-07','13:02:46','13:02:46',NULL,NULL,'x','x');
+INSERT INTO `t2` VALUES (28,5,6,'2006-10-10','2006-10-10','21:44:25','21:44:25','2001-04-25 01:26:12','2001-04-25 01:26:12','m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'1900-01-01','1900-01-01','22:43:58','22:43:58','2000-12-27 00:00:00','2000-12-27 00:00:00','c','c');
+CREATE TABLE `t3` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+INSERT INTO `t3` VALUES (1,1,7,'1900-01-01','1900-01-01','01:13:38','01:13:38','2005-02-05 00:00:00','2005-02-05 00:00:00','f','f');
+CREATE TABLE `t4` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+INSERT INTO `t4` VALUES (1,6,NULL,'2003-05-12','2003-05-12',NULL,NULL,'2000-09-12 00:00:00','2000-09-12 00:00:00','r','r');
+INSERT INTO `t4` VALUES (2,8,0,'2003-01-07','2003-01-07','14:34:45','14:34:45','2004-08-10 09:09:31','2004-08-10 09:09:31','c','c');
+INSERT INTO `t4` VALUES (3,6,0,NULL,NULL,'11:49:48','11:49:48','2005-03-21 04:31:40','2005-03-21 04:31:40','o','o');
+INSERT INTO `t4` VALUES (4,6,7,'2005-03-12','2005-03-12','18:12:55','18:12:55','2002-10-25 23:50:35','2002-10-25 23:50:35','c','c');
+INSERT INTO `t4` VALUES (5,3,8,'2000-08-02','2000-08-02','18:30:05','18:30:05','2001-04-01 21:14:04','2001-04-01 21:14:04','d','d');
+INSERT INTO `t4` VALUES (6,9,4,'1900-01-01','1900-01-01','14:19:30','14:19:30','2005-03-12 06:02:34','2005-03-12 06:02:34','v','v');
+INSERT INTO `t4` VALUES (7,2,6,'2006-07-06','2006-07-06','05:20:04','05:20:04','2001-05-06 14:49:12','2001-05-06 14:49:12','m','m');
+INSERT INTO `t4` VALUES (8,1,5,'2006-12-24','2006-12-24','20:29:31','20:29:31','2004-04-25 00:00:00','2004-04-25 00:00:00','j','j');
+INSERT INTO `t4` VALUES (9,8,NULL,'2004-11-16','2004-11-16','07:08:09','07:08:09','2001-03-22 18:38:43','2001-03-22 18:38:43','f','f');
+INSERT INTO `t4` VALUES (10,0,NULL,'2002-09-09','2002-09-09','14:49:14','14:49:14','2006-04-25 21:03:02','2006-04-25 21:03:02','n','n');
+INSERT INTO `t4` VALUES (11,9,8,NULL,NULL,'00:00:00','00:00:00','2009-09-07 18:40:43','2009-09-07 18:40:43','z','z');
+INSERT INTO `t4` VALUES (12,8,8,'2008-06-24','2008-06-24','09:58:06','09:58:06','2004-03-23 00:00:00','2004-03-23 00:00:00','h','h');
+INSERT INTO `t4` VALUES (13,NULL,8,'2001-04-21','2001-04-21',NULL,NULL,'2009-04-15 00:08:29','2009-04-15 00:08:29','q','q');
+INSERT INTO `t4` VALUES (14,0,1,'2003-11-22','2003-11-22','18:24:16','18:24:16','2000-04-21 00:00:00','2000-04-21 00:00:00','w','w');
+INSERT INTO `t4` VALUES (15,5,1,'2004-09-12','2004-09-12','17:39:57','17:39:57','2000-02-17 19:41:23','2000-02-17 19:41:23','z','z');
+INSERT INTO `t4` VALUES (16,1,5,'2006-06-20','2006-06-20','08:23:21','08:23:21','2003-09-20 07:38:14','2003-09-20 07:38:14','j','j');
+INSERT INTO `t4` VALUES (17,1,2,NULL,NULL,NULL,NULL,'2000-11-28 20:42:12','2000-11-28 20:42:12','a','a');
+INSERT INTO `t4` VALUES (18,6,7,'2001-11-25','2001-11-25','21:50:46','21:50:46','2005-06-12 11:13:17','2005-06-12 11:13:17','m','m');
+INSERT INTO `t4` VALUES (19,6,6,'2004-10-26','2004-10-26','12:33:17','12:33:17','1900-01-01 00:00:00','1900-01-01 00:00:00','n','n');
+INSERT INTO `t4` VALUES (20,1,4,'2005-01-19','2005-01-19','03:06:43','03:06:43','2006-02-09 20:41:06','2006-02-09 20:41:06','e','e');
+INSERT INTO `t4` VALUES (21,8,7,'2008-07-06','2008-07-06','03:46:14','03:46:14','2004-05-22 01:05:57','2004-05-22 01:05:57','u','u');
+INSERT INTO `t4` VALUES (22,1,0,'1900-01-01','1900-01-01','20:34:52','20:34:52','2004-03-04 13:46:31','2004-03-04 13:46:31','s','s');
+INSERT INTO `t4` VALUES (23,0,9,'1900-01-01','1900-01-01',NULL,NULL,'1900-01-01 00:00:00','1900-01-01 00:00:00','u','u');
+INSERT INTO `t4` VALUES (24,4,3,'2004-06-08','2004-06-08','10:41:20','10:41:20','2004-10-20 07:20:19','2004-10-20 07:20:19','r','r');
+INSERT INTO `t4` VALUES (25,9,5,'2007-02-20','2007-02-20','08:43:11','08:43:11','2006-04-17 00:00:00','2006-04-17 00:00:00','g','g');
+INSERT INTO `t4` VALUES (26,8,1,'2008-06-18','2008-06-18',NULL,NULL,'2000-10-27 00:00:00','2000-10-27 00:00:00','o','o');
+INSERT INTO `t4` VALUES (27,5,1,'2008-05-15','2008-05-15','10:17:51','10:17:51','2007-04-14 08:54:06','2007-04-14 08:54:06','w','w');
+INSERT INTO `t4` VALUES (28,9,5,'2005-10-06','2005-10-06','06:34:09','06:34:09','2008-04-12 17:03:52','2008-04-12 17:03:52','b','b');
+INSERT INTO `t4` VALUES (29,5,9,NULL,NULL,'21:22:47','21:22:47','2007-02-19 17:37:09','2007-02-19 17:37:09',NULL,NULL);
+INSERT INTO `t4` VALUES (30,NULL,2,'2006-10-12','2006-10-12','04:02:32','04:02:32','1900-01-01 00:00:00','1900-01-01 00:00:00','y','y');
+INSERT INTO `t4` VALUES (31,NULL,5,'2005-01-24','2005-01-24','02:33:14','02:33:14','2001-10-10 08:32:27','2001-10-10 08:32:27','y','y');
+INSERT INTO `t4` VALUES (32,105,248,'2009-06-27','2009-06-27','16:32:56','16:32:56',NULL,NULL,'u','u');
+INSERT INTO `t4` VALUES (33,0,0,NULL,NULL,'21:32:42','21:32:42','2001-12-16 05:31:53','2001-12-16 05:31:53','p','p');
+INSERT INTO `t4` VALUES (34,3,8,NULL,NULL,'23:04:47','23:04:47','2003-07-19 18:03:28','2003-07-19 18:03:28','s','s');
+INSERT INTO `t4` VALUES (35,1,1,'1900-01-01','1900-01-01','22:05:43','22:05:43','2001-03-27 11:44:10','2001-03-27 11:44:10','e','e');
+INSERT INTO `t4` VALUES (36,75,255,'2005-12-22','2005-12-22','02:05:45','02:05:45','2008-06-15 02:13:00','2008-06-15 02:13:00','d','d');
+INSERT INTO `t4` VALUES (37,9,9,'2005-05-03','2005-05-03','00:00:00','00:00:00','2009-03-14 21:29:56','2009-03-14 21:29:56','d','d');
+INSERT INTO `t4` VALUES (38,7,9,'2003-05-27','2003-05-27','18:09:07','18:09:07','2005-01-02 00:00:00','2005-01-02 00:00:00','c','c');
+INSERT INTO `t4` VALUES (39,NULL,3,'2006-05-25','2006-05-25','10:54:06','10:54:06','2007-07-16 04:44:07','2007-07-16 04:44:07','b','b');
+INSERT INTO `t4` VALUES (40,NULL,9,NULL,NULL,'23:15:50','23:15:50','2003-08-26 21:38:26','2003-08-26 21:38:26','t','t');
+INSERT INTO `t4` VALUES (41,4,6,'2009-01-04','2009-01-04','10:17:40','10:17:40','2004-04-19 04:18:47','2004-04-19 04:18:47',NULL,NULL);
+INSERT INTO `t4` VALUES (42,0,4,'2009-02-14','2009-02-14','03:37:09','03:37:09','2000-01-06 20:32:48','2000-01-06 20:32:48','y','y');
+INSERT INTO `t4` VALUES (43,204,60,'2003-01-16','2003-01-16','22:26:06','22:26:06','2006-06-23 13:27:17','2006-06-23 13:27:17','c','c');
+INSERT INTO `t4` VALUES (44,0,7,'1900-01-01','1900-01-01','17:10:38','17:10:38','2007-11-27 00:00:00','2007-11-27 00:00:00','d','d');
+INSERT INTO `t4` VALUES (45,9,1,'2007-06-26','2007-06-26','00:00:00','00:00:00','2002-04-03 12:06:51','2002-04-03 12:06:51','x','x');
+INSERT INTO `t4` VALUES (46,8,6,'2004-03-27','2004-03-27','17:08:49','17:08:49','2008-12-28 09:47:42','2008-12-28 09:47:42','p','p');
+INSERT INTO `t4` VALUES (47,7,4,NULL,NULL,'19:04:40','19:04:40','2002-04-04 10:07:54','2002-04-04 10:07:54','e','e');
+INSERT INTO `t4` VALUES (48,8,NULL,'2005-06-06','2005-06-06','20:53:28','20:53:28','2003-04-26 02:55:13','2003-04-26 02:55:13','g','g');
+INSERT INTO `t4` VALUES (49,NULL,8,'2003-03-02','2003-03-02','11:46:03','11:46:03',NULL,NULL,'x','x');
+INSERT INTO `t4` VALUES (50,6,0,'2004-05-13','2004-05-13',NULL,NULL,'2009-02-19 03:17:06','2009-02-19 03:17:06','s','s');
+INSERT INTO `t4` VALUES (51,5,8,'2005-09-13','2005-09-13','10:58:07','10:58:07','1900-01-01 00:00:00','1900-01-01 00:00:00','e','e');
+INSERT INTO `t4` VALUES (52,2,151,'2005-10-03','2005-10-03','00:00:00','00:00:00','2000-11-10 08:20:01','2000-11-10 08:20:01','l','l');
+INSERT INTO `t4` VALUES (53,3,7,'2005-10-14','2005-10-14','09:43:15','09:43:15','2008-02-10 00:00:00','2008-02-10 00:00:00','p','p');
+INSERT INTO `t4` VALUES (54,7,6,NULL,NULL,'21:40:32','21:40:32','1900-01-01 00:00:00','1900-01-01 00:00:00','h','h');
+INSERT INTO `t4` VALUES (55,NULL,NULL,'2005-09-16','2005-09-16','00:17:44','00:17:44',NULL,NULL,'m','m');
+INSERT INTO `t4` VALUES (56,145,23,'2005-03-10','2005-03-10','16:47:26','16:47:26','2001-02-05 02:01:50','2001-02-05 02:01:50','n','n');
+INSERT INTO `t4` VALUES (57,0,2,'2000-06-19','2000-06-19','00:00:00','00:00:00','2000-10-28 08:44:25','2000-10-28 08:44:25','v','v');
+INSERT INTO `t4` VALUES (58,1,4,'2002-11-03','2002-11-03','05:25:59','05:25:59','2005-03-20 10:53:59','2005-03-20 10:53:59','b','b');
+INSERT INTO `t4` VALUES (59,7,NULL,'2009-01-05','2009-01-05','00:00:00','00:00:00','2001-06-02 13:54:13','2001-06-02 13:54:13','x','x');
+INSERT INTO `t4` VALUES (60,3,NULL,'2003-05-22','2003-05-22','20:33:04','20:33:04','1900-01-01 00:00:00','1900-01-01 00:00:00','r','r');
+INSERT INTO `t4` VALUES (61,NULL,77,'2005-07-02','2005-07-02','00:46:12','00:46:12','2009-07-16 13:05:43','2009-07-16 13:05:43','t','t');
+INSERT INTO `t4` VALUES (62,2,NULL,'1900-01-01','1900-01-01','00:00:00','00:00:00','2009-03-26 23:16:20','2009-03-26 23:16:20','w','w');
+INSERT INTO `t4` VALUES (63,2,NULL,'2006-06-21','2006-06-21','02:13:59','02:13:59','2003-02-06 18:12:15','2003-02-06 18:12:15','w','w');
+INSERT INTO `t4` VALUES (64,2,7,NULL,NULL,'02:54:47','02:54:47','2006-06-05 03:22:51','2006-06-05 03:22:51','k','k');
+INSERT INTO `t4` VALUES (65,8,1,'2005-12-16','2005-12-16','18:13:59','18:13:59','2002-02-10 05:47:27','2002-02-10 05:47:27','a','a');
+INSERT INTO `t4` VALUES (66,6,9,'2004-11-05','2004-11-05','13:53:08','13:53:08','2001-08-01 08:50:52','2001-08-01 08:50:52','t','t');
+INSERT INTO `t4` VALUES (67,1,6,NULL,NULL,'22:21:30','22:21:30','1900-01-01 00:00:00','1900-01-01 00:00:00','z','z');
+INSERT INTO `t4` VALUES (68,NULL,2,'2004-09-14','2004-09-14','11:41:50','11:41:50',NULL,NULL,'e','e');
+INSERT INTO `t4` VALUES (69,1,3,'2002-04-06','2002-04-06','15:20:02','15:20:02','1900-01-01 00:00:00','1900-01-01 00:00:00','q','q');
+INSERT INTO `t4` VALUES (70,0,0,NULL,NULL,NULL,NULL,'2000-09-23 00:00:00','2000-09-23 00:00:00','e','e');
+INSERT INTO `t4` VALUES (71,4,NULL,'2002-11-13','2002-11-13',NULL,NULL,'2007-07-09 08:32:49','2007-07-09 08:32:49','v','v');
+INSERT INTO `t4` VALUES (72,1,6,'2006-05-27','2006-05-27','07:51:52','07:51:52','2000-01-05 00:00:00','2000-01-05 00:00:00','d','d');
+INSERT INTO `t4` VALUES (73,1,3,'2000-12-22','2000-12-22','00:00:00','00:00:00','2000-09-24 00:00:00','2000-09-24 00:00:00','u','u');
+INSERT INTO `t4` VALUES (74,27,195,'2004-02-21','2004-02-21',NULL,NULL,'2005-05-06 00:00:00','2005-05-06 00:00:00','o','o');
+INSERT INTO `t4` VALUES (75,4,5,'2009-05-15','2009-05-15',NULL,NULL,'2000-03-11 00:00:00','2000-03-11 00:00:00','b','b');
+INSERT INTO `t4` VALUES (76,6,2,'2008-12-12','2008-12-12','12:31:05','12:31:05','2001-09-02 16:17:35','2001-09-02 16:17:35','c','c');
+INSERT INTO `t4` VALUES (77,2,7,'2000-04-15','2000-04-15','00:00:00','00:00:00','2006-04-25 05:43:44','2006-04-25 05:43:44','q','q');
+INSERT INTO `t4` VALUES (78,248,25,NULL,NULL,'01:16:45','01:16:45','2009-10-25 22:04:02','2009-10-25 22:04:02',NULL,NULL);
+INSERT INTO `t4` VALUES (79,NULL,NULL,'2001-10-18','2001-10-18','20:38:54','20:38:54','2004-08-06 00:00:00','2004-08-06 00:00:00','h','h');
+INSERT INTO `t4` VALUES (80,9,0,'2008-05-25','2008-05-25','00:30:15','00:30:15','2001-11-27 05:07:57','2001-11-27 05:07:57','d','d');
+INSERT INTO `t4` VALUES (81,75,98,'2004-12-02','2004-12-02','23:46:36','23:46:36','2009-06-28 03:18:39','2009-06-28 03:18:39','w','w');
+INSERT INTO `t4` VALUES (82,2,6,'2002-02-15','2002-02-15','19:03:13','19:03:13','2000-03-12 00:00:00','2000-03-12 00:00:00','m','m');
+INSERT INTO `t4` VALUES (83,9,5,'2002-03-03','2002-03-03','10:54:27','10:54:27',NULL,NULL,'i','i');
+INSERT INTO `t4` VALUES (84,4,0,NULL,NULL,'00:25:47','00:25:47','2007-10-20 00:00:00','2007-10-20 00:00:00','w','w');
+INSERT INTO `t4` VALUES (85,0,3,'2003-01-26','2003-01-26','08:44:27','08:44:27','2009-09-27 00:00:00','2009-09-27 00:00:00','f','f');
+INSERT INTO `t4` VALUES (86,0,1,'2001-12-19','2001-12-19','08:15:38','08:15:38','2002-07-16 00:00:00','2002-07-16 00:00:00','k','k');
+INSERT INTO `t4` VALUES (87,1,1,'2001-08-07','2001-08-07','19:56:21','19:56:21','2005-02-20 00:00:00','2005-02-20 00:00:00','v','v');
+INSERT INTO `t4` VALUES (88,119,147,'2005-02-16','2005-02-16','00:00:00','00:00:00',NULL,NULL,'c','c');
+INSERT INTO `t4` VALUES (89,1,3,'2006-06-10','2006-06-10','20:50:52','20:50:52','2001-07-16 00:00:00','2001-07-16 00:00:00','y','y');
+INSERT INTO `t4` VALUES (90,7,3,NULL,NULL,'03:54:39','03:54:39','2009-05-20 21:04:12','2009-05-20 21:04:12','h','h');
+INSERT INTO `t4` VALUES (91,2,NULL,'2005-04-06','2005-04-06','23:58:17','23:58:17','2002-03-13 10:55:40','2002-03-13 10:55:40',NULL,NULL);
+INSERT INTO `t4` VALUES (92,7,2,'2003-04-27','2003-04-27','12:54:58','12:54:58','2005-07-12 00:00:00','2005-07-12 00:00:00','t','t');
+INSERT INTO `t4` VALUES (93,2,1,'2005-10-13','2005-10-13','04:02:43','04:02:43','2006-07-22 09:46:34','2006-07-22 09:46:34','l','l');
+INSERT INTO `t4` VALUES (94,6,8,'2003-10-02','2003-10-02','11:31:12','11:31:12','2001-09-01 00:00:00','2001-09-01 00:00:00','a','a');
+INSERT INTO `t4` VALUES (95,4,8,'2005-09-09','2005-09-09','20:20:04','20:20:04','2002-05-27 18:38:45','2002-05-27 18:38:45','r','r');
+INSERT INTO `t4` VALUES (96,5,8,NULL,NULL,'00:22:24','00:22:24',NULL,NULL,'s','s');
+INSERT INTO `t4` VALUES (97,7,0,'2006-02-15','2006-02-15','10:09:31','10:09:31',NULL,NULL,'z','z');
+INSERT INTO `t4` VALUES (98,1,1,'1900-01-01','1900-01-01',NULL,NULL,'2009-08-08 22:38:53','2009-08-08 22:38:53','j','j');
+INSERT INTO `t4` VALUES (99,7,8,'2003-12-24','2003-12-24','18:45:35','18:45:35',NULL,NULL,'c','c');
+INSERT INTO `t4` VALUES (100,2,5,'2001-07-26','2001-07-26','11:49:25','11:49:25','2007-04-25 05:08:49','2007-04-25 05:08:49','f','f');
+SET @@optimizer_switch='subquery_cache=off';
+/* cache is off */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+COUNT( DISTINCT table2 .`col_int_key` ) (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) field10
+1 NULL c
+1 NULL d
+1 NULL e
+1 NULL f
+1 NULL h
+1 NULL j
+2 NULL k
+2 NULL m
+1 NULL n
+1 NULL o
+0 NULL r
+2 NULL t
+1 NULL u
+1 NULL w
+1 NULL y
+SET @@optimizer_switch='subquery_cache=on';
+/* cache is on */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+COUNT( DISTINCT table2 .`col_int_key` ) (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) field10
+1 NULL c
+1 NULL d
+1 NULL e
+1 NULL f
+1 NULL h
+1 NULL j
+2 NULL k
+2 NULL m
+1 NULL n
+1 NULL o
+0 NULL r
+2 NULL t
+1 NULL u
+1 NULL w
+1 NULL y
+drop table t1,t2,t3,t4;
+set @@optimizer_switch= default;
+#launchpad BUG#609045
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,7,8,'v','v');
+INSERT INTO `t2` VALUES (11,1,9,'r','r');
+INSERT INTO `t2` VALUES (12,5,9,'a','a');
+INSERT INTO `t2` VALUES (13,3,186,'m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,'y','y');
+INSERT INTO `t2` VALUES (15,92,2,'j','j');
+INSERT INTO `t2` VALUES (16,7,3,'d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'z','z');
+INSERT INTO `t2` VALUES (18,3,133,'e','e');
+INSERT INTO `t2` VALUES (19,5,1,'h','h');
+INSERT INTO `t2` VALUES (20,1,8,'b','b');
+INSERT INTO `t2` VALUES (21,2,5,'s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'e','e');
+INSERT INTO `t2` VALUES (23,1,8,'j','j');
+INSERT INTO `t2` VALUES (24,0,6,'e','e');
+INSERT INTO `t2` VALUES (25,210,51,'f','f');
+INSERT INTO `t2` VALUES (26,8,4,'v','v');
+INSERT INTO `t2` VALUES (27,7,7,'x','x');
+INSERT INTO `t2` VALUES (28,5,6,'m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'c','c');
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,'w','w');
+INSERT INTO `t1` VALUES (2,7,9,'m','m');
+INSERT INTO `t1` VALUES (3,9,3,'m','m');
+INSERT INTO `t1` VALUES (4,7,9,'k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'r','r');
+INSERT INTO `t1` VALUES (6,2,9,'t','t');
+INSERT INTO `t1` VALUES (7,6,3,'j','j');
+INSERT INTO `t1` VALUES (8,8,8,'u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'h','h');
+INSERT INTO `t1` VALUES (10,5,53,'o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'k','k');
+INSERT INTO `t1` VALUES (13,188,166,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,'n','n');
+INSERT INTO `t1` VALUES (15,1,0,'t','t');
+INSERT INTO `t1` VALUES (16,1,1,'c','c');
+INSERT INTO `t1` VALUES (17,0,9,'m','m');
+INSERT INTO `t1` VALUES (18,9,5,'y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'f','f');
+INSERT INTO `t1` VALUES (20,4,2,'d','d');
+SET @@optimizer_switch = 'subquery_cache=off';
+/* cache is off */ SELECT SUM( DISTINCT table1 .`pk` ) , (
+SELECT MAX( `col_int_nokey` )
+FROM t1
+WHERE table1 .`pk` ) field3
+FROM t1 table1
+JOIN (
+t1 table2
+JOIN t2 table3
+ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+)
+ON table3 .`col_varchar_key` = table2 .`col_varchar_nokey`
+GROUP BY field3 ;
+SUM( DISTINCT table1 .`pk` ) field3
+210 188
+SET @@optimizer_switch = 'subquery_cache=on';
+/* cache is on */ SELECT SUM( DISTINCT table1 .`pk` ) , (
+SELECT MAX( `col_int_nokey` )
+FROM t1
+WHERE table1 .`pk` ) field3
+FROM t1 table1
+JOIN (
+t1 table2
+JOIN t2 table3
+ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+)
+ON table3 .`col_varchar_key` = table2 .`col_varchar_nokey`
+GROUP BY field3 ;
+SUM( DISTINCT table1 .`pk` ) field3
+210 188
+drop table t1,t2;
+set @@optimizer_switch= default;
+#launchpad BUG#609052
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,7,8,'01:27:35','v','v');
+INSERT INTO `t2` VALUES (11,1,9,'19:48:31','r','r');
+INSERT INTO `t2` VALUES (12,5,9,'00:00:00','a','a');
+INSERT INTO `t2` VALUES (13,3,186,'19:53:05','m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,'19:18:56','y','y');
+INSERT INTO `t2` VALUES (15,92,2,'10:55:12','j','j');
+INSERT INTO `t2` VALUES (16,7,3,'00:25:00','d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'12:35:47','z','z');
+INSERT INTO `t2` VALUES (18,3,133,'19:53:03','e','e');
+INSERT INTO `t2` VALUES (19,5,1,'17:53:30','h','h');
+INSERT INTO `t2` VALUES (20,1,8,'11:35:49','b','b');
+INSERT INTO `t2` VALUES (21,2,5,NULL,'s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'06:01:40','e','e');
+INSERT INTO `t2` VALUES (23,1,8,'05:45:11','j','j');
+INSERT INTO `t2` VALUES (24,0,6,'00:00:00','e','e');
+INSERT INTO `t2` VALUES (25,210,51,'00:00:00','f','f');
+INSERT INTO `t2` VALUES (26,8,4,'06:11:01','v','v');
+INSERT INTO `t2` VALUES (27,7,7,'13:02:46','x','x');
+INSERT INTO `t2` VALUES (28,5,6,'21:44:25','m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'22:43:58','c','c');
+CREATE TABLE `t4` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t4` VALUES (1,6,NULL,NULL,'r','r');
+INSERT INTO `t4` VALUES (2,8,0,'14:34:45','c','c');
+INSERT INTO `t4` VALUES (3,6,0,'11:49:48','o','o');
+INSERT INTO `t4` VALUES (4,6,7,'18:12:55','c','c');
+INSERT INTO `t4` VALUES (5,3,8,'18:30:05','d','d');
+INSERT INTO `t4` VALUES (6,9,4,'14:19:30','v','v');
+INSERT INTO `t4` VALUES (7,2,6,'05:20:04','m','m');
+INSERT INTO `t4` VALUES (8,1,5,'20:29:31','j','j');
+INSERT INTO `t4` VALUES (9,8,NULL,'07:08:09','f','f');
+INSERT INTO `t4` VALUES (10,0,NULL,'14:49:14','n','n');
+INSERT INTO `t4` VALUES (11,9,8,'00:00:00','z','z');
+INSERT INTO `t4` VALUES (12,8,8,'09:58:06','h','h');
+INSERT INTO `t4` VALUES (13,NULL,8,NULL,'q','q');
+INSERT INTO `t4` VALUES (14,0,1,'18:24:16','w','w');
+INSERT INTO `t4` VALUES (15,5,1,'17:39:57','z','z');
+INSERT INTO `t4` VALUES (16,1,5,'08:23:21','j','j');
+INSERT INTO `t4` VALUES (17,1,2,NULL,'a','a');
+INSERT INTO `t4` VALUES (18,6,7,'21:50:46','m','m');
+INSERT INTO `t4` VALUES (19,6,6,'12:33:17','n','n');
+INSERT INTO `t4` VALUES (20,1,4,'03:06:43','e','e');
+INSERT INTO `t4` VALUES (21,8,7,'03:46:14','u','u');
+INSERT INTO `t4` VALUES (22,1,0,'20:34:52','s','s');
+INSERT INTO `t4` VALUES (23,0,9,NULL,'u','u');
+INSERT INTO `t4` VALUES (24,4,3,'10:41:20','r','r');
+INSERT INTO `t4` VALUES (25,9,5,'08:43:11','g','g');
+INSERT INTO `t4` VALUES (26,8,1,NULL,'o','o');
+INSERT INTO `t4` VALUES (27,5,1,'10:17:51','w','w');
+INSERT INTO `t4` VALUES (28,9,5,'06:34:09','b','b');
+INSERT INTO `t4` VALUES (29,5,9,'21:22:47',NULL,NULL);
+INSERT INTO `t4` VALUES (30,NULL,2,'04:02:32','y','y');
+INSERT INTO `t4` VALUES (31,NULL,5,'02:33:14','y','y');
+INSERT INTO `t4` VALUES (32,105,248,'16:32:56','u','u');
+INSERT INTO `t4` VALUES (33,0,0,'21:32:42','p','p');
+INSERT INTO `t4` VALUES (34,3,8,'23:04:47','s','s');
+INSERT INTO `t4` VALUES (35,1,1,'22:05:43','e','e');
+INSERT INTO `t4` VALUES (36,75,255,'02:05:45','d','d');
+INSERT INTO `t4` VALUES (37,9,9,'00:00:00','d','d');
+INSERT INTO `t4` VALUES (38,7,9,'18:09:07','c','c');
+INSERT INTO `t4` VALUES (39,NULL,3,'10:54:06','b','b');
+INSERT INTO `t4` VALUES (40,NULL,9,'23:15:50','t','t');
+INSERT INTO `t4` VALUES (41,4,6,'10:17:40',NULL,NULL);
+INSERT INTO `t4` VALUES (42,0,4,'03:37:09','y','y');
+INSERT INTO `t4` VALUES (43,204,60,'22:26:06','c','c');
+INSERT INTO `t4` VALUES (44,0,7,'17:10:38','d','d');
+INSERT INTO `t4` VALUES (45,9,1,'00:00:00','x','x');
+INSERT INTO `t4` VALUES (46,8,6,'17:08:49','p','p');
+INSERT INTO `t4` VALUES (47,7,4,'19:04:40','e','e');
+INSERT INTO `t4` VALUES (48,8,NULL,'20:53:28','g','g');
+INSERT INTO `t4` VALUES (49,NULL,8,'11:46:03','x','x');
+INSERT INTO `t4` VALUES (50,6,0,NULL,'s','s');
+INSERT INTO `t4` VALUES (51,5,8,'10:58:07','e','e');
+INSERT INTO `t4` VALUES (52,2,151,'00:00:00','l','l');
+INSERT INTO `t4` VALUES (53,3,7,'09:43:15','p','p');
+INSERT INTO `t4` VALUES (54,7,6,'21:40:32','h','h');
+INSERT INTO `t4` VALUES (55,NULL,NULL,'00:17:44','m','m');
+INSERT INTO `t4` VALUES (56,145,23,'16:47:26','n','n');
+INSERT INTO `t4` VALUES (57,0,2,'00:00:00','v','v');
+INSERT INTO `t4` VALUES (58,1,4,'05:25:59','b','b');
+INSERT INTO `t4` VALUES (59,7,NULL,'00:00:00','x','x');
+INSERT INTO `t4` VALUES (60,3,NULL,'20:33:04','r','r');
+INSERT INTO `t4` VALUES (61,NULL,77,'00:46:12','t','t');
+INSERT INTO `t4` VALUES (62,2,NULL,'00:00:00','w','w');
+INSERT INTO `t4` VALUES (63,2,NULL,'02:13:59','w','w');
+INSERT INTO `t4` VALUES (64,2,7,'02:54:47','k','k');
+INSERT INTO `t4` VALUES (65,8,1,'18:13:59','a','a');
+INSERT INTO `t4` VALUES (66,6,9,'13:53:08','t','t');
+INSERT INTO `t4` VALUES (67,1,6,'22:21:30','z','z');
+INSERT INTO `t4` VALUES (68,NULL,2,'11:41:50','e','e');
+INSERT INTO `t4` VALUES (69,1,3,'15:20:02','q','q');
+INSERT INTO `t4` VALUES (70,0,0,NULL,'e','e');
+INSERT INTO `t4` VALUES (71,4,NULL,NULL,'v','v');
+INSERT INTO `t4` VALUES (72,1,6,'07:51:52','d','d');
+INSERT INTO `t4` VALUES (73,1,3,'00:00:00','u','u');
+INSERT INTO `t4` VALUES (74,27,195,NULL,'o','o');
+INSERT INTO `t4` VALUES (75,4,5,NULL,'b','b');
+INSERT INTO `t4` VALUES (76,6,2,'12:31:05','c','c');
+INSERT INTO `t4` VALUES (77,2,7,'00:00:00','q','q');
+INSERT INTO `t4` VALUES (78,248,25,'01:16:45',NULL,NULL);
+INSERT INTO `t4` VALUES (79,NULL,NULL,'20:38:54','h','h');
+INSERT INTO `t4` VALUES (80,9,0,'00:30:15','d','d');
+INSERT INTO `t4` VALUES (81,75,98,'23:46:36','w','w');
+INSERT INTO `t4` VALUES (82,2,6,'19:03:13','m','m');
+INSERT INTO `t4` VALUES (83,9,5,'10:54:27','i','i');
+INSERT INTO `t4` VALUES (84,4,0,'00:25:47','w','w');
+INSERT INTO `t4` VALUES (85,0,3,'08:44:27','f','f');
+INSERT INTO `t4` VALUES (86,0,1,'08:15:38','k','k');
+INSERT INTO `t4` VALUES (87,1,1,'19:56:21','v','v');
+INSERT INTO `t4` VALUES (88,119,147,'00:00:00','c','c');
+INSERT INTO `t4` VALUES (89,1,3,'20:50:52','y','y');
+INSERT INTO `t4` VALUES (90,7,3,'03:54:39','h','h');
+INSERT INTO `t4` VALUES (91,2,NULL,'23:58:17',NULL,NULL);
+INSERT INTO `t4` VALUES (92,7,2,'12:54:58','t','t');
+INSERT INTO `t4` VALUES (93,2,1,'04:02:43','l','l');
+INSERT INTO `t4` VALUES (94,6,8,'11:31:12','a','a');
+INSERT INTO `t4` VALUES (95,4,8,'20:20:04','r','r');
+INSERT INTO `t4` VALUES (96,5,8,'00:22:24','s','s');
+INSERT INTO `t4` VALUES (97,7,0,'10:09:31','z','z');
+INSERT INTO `t4` VALUES (98,1,1,NULL,'j','j');
+INSERT INTO `t4` VALUES (99,7,8,'18:45:35','c','c');
+INSERT INTO `t4` VALUES (100,2,5,'11:49:25','f','f');
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,'11:28:45','w','w');
+INSERT INTO `t1` VALUES (2,7,9,'20:25:14','m','m');
+INSERT INTO `t1` VALUES (3,9,3,'13:47:24','m','m');
+INSERT INTO `t1` VALUES (4,7,9,'19:24:11','k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'15:59:13','r','r');
+INSERT INTO `t1` VALUES (6,2,9,'00:00:00','t','t');
+INSERT INTO `t1` VALUES (7,6,3,'15:15:04','j','j');
+INSERT INTO `t1` VALUES (8,8,8,'11:32:06','u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'18:32:33','h','h');
+INSERT INTO `t1` VALUES (10,5,53,'15:19:25','o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,'19:03:19',NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'00:39:46','k','k');
+INSERT INTO `t1` VALUES (13,188,166,NULL,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,'00:00:00','n','n');
+INSERT INTO `t1` VALUES (15,1,0,'13:12:11','t','t');
+INSERT INTO `t1` VALUES (16,1,1,'04:56:48','c','c');
+INSERT INTO `t1` VALUES (17,0,9,'19:56:05','m','m');
+INSERT INTO `t1` VALUES (18,9,5,'19:35:19','y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'05:03:03','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'18:38:59','d','d');
+CREATE TABLE `t3` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO `t3` VALUES (10,8,8,'18:27:58',NULL,NULL);
+CREATE TABLE `t5` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO `t5` VALUES (1,1,7,'01:13:38','f','f');
+SET @@optimizer_switch='subquery_cache=off';
+/* cache is off */ SELECT SQL_SMALL_RESULT MAX( DISTINCT table1 . `col_varchar_key` ) AS field1 , MIN( table1 . `col_varchar_nokey` ) AS field2 , COUNT( table1 . `col_varchar_key` ) AS field3 , table2 . `col_time_key` AS field4 , COUNT( DISTINCT table2 . `col_int_key` ) AS field5 , (
+SELECT MAX( SUBQUERY1_t2 . `col_int_nokey` ) AS SUBQUERY1_field1
+FROM ( t3 AS SUBQUERY1_t1 INNER JOIN t1 AS SUBQUERY1_t2 ON (SUBQUERY1_t2 . `col_varchar_key` = SUBQUERY1_t1 . `col_varchar_nokey` ) )
+WHERE SUBQUERY1_t2 . `pk` < SUBQUERY1_t2 . `pk` ) AS field6 , COUNT( table1 . `col_varchar_nokey` ) AS field7 , COUNT( table2 . `pk` ) AS field8 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_key` ) AS SUBQUERY2_field1
+FROM ( t5 AS SUBQUERY2_t1 LEFT JOIN t2 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `col_int_key` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` != table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_varchar_nokey` >= 'o' ) AS field9 , CONCAT ( table1 . `col_varchar_key` , table2 . `col_varchar_nokey` ) AS field10
+FROM ( t4 AS table1 LEFT JOIN ( ( t1 AS table2 STRAIGHT_JOIN t1 AS table3 ON (table3 . `col_int_nokey` = table2 . `pk` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) )
+WHERE ( EXISTS (
+SELECT SUBQUERY3_t1 . `pk` AS SUBQUERY3_field1
+FROM ( t4 AS SUBQUERY3_t1 INNER JOIN t4 AS SUBQUERY3_t2 ON (SUBQUERY3_t2 . `col_varchar_key` = SUBQUERY3_t1 . `col_varchar_key` ) )
+WHERE SUBQUERY3_t1 . `col_int_key` > table3 . `pk` AND SUBQUERY3_t1 . `pk` != table3 . `pk` ) ) AND ( table1 . `pk` > 116 AND table1 . `pk` < ( 116 + 175 ) OR table1 . `pk` IN (251) ) OR table1 . `col_int_nokey` = table1 . `col_int_nokey`
+GROUP BY field4, field6, field9, field10
+HAVING field10 = 'c'
+;
+field1 field2 field3 field4 field5 field6 field7 field8 field9 field10
+SET @@optimizer_switch='subquery_cache=on';
+/* cache is on */ SELECT SQL_SMALL_RESULT MAX( DISTINCT table1 . `col_varchar_key` ) AS field1 , MIN( table1 . `col_varchar_nokey` ) AS field2 , COUNT( table1 . `col_varchar_key` ) AS field3 , table2 . `col_time_key` AS field4 , COUNT( DISTINCT table2 . `col_int_key` ) AS field5 , (
+SELECT MAX( SUBQUERY1_t2 . `col_int_nokey` ) AS SUBQUERY1_field1
+FROM ( t3 AS SUBQUERY1_t1 INNER JOIN t1 AS SUBQUERY1_t2 ON (SUBQUERY1_t2 . `col_varchar_key` = SUBQUERY1_t1 . `col_varchar_nokey` ) )
+WHERE SUBQUERY1_t2 . `pk` < SUBQUERY1_t2 . `pk` ) AS field6 , COUNT( table1 . `col_varchar_nokey` ) AS field7 , COUNT( table2 . `pk` ) AS field8 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_key` ) AS SUBQUERY2_field1
+FROM ( t5 AS SUBQUERY2_t1 LEFT JOIN t2 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `col_int_key` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` != table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_varchar_nokey` >= 'o' ) AS field9 , CONCAT ( table1 . `col_varchar_key` , table2 . `col_varchar_nokey` ) AS field10
+FROM ( t4 AS table1 LEFT JOIN ( ( t1 AS table2 STRAIGHT_JOIN t1 AS table3 ON (table3 . `col_int_nokey` = table2 . `pk` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) )
+WHERE ( EXISTS (
+SELECT SUBQUERY3_t1 . `pk` AS SUBQUERY3_field1
+FROM ( t4 AS SUBQUERY3_t1 INNER JOIN t4 AS SUBQUERY3_t2 ON (SUBQUERY3_t2 . `col_varchar_key` = SUBQUERY3_t1 . `col_varchar_key` ) )
+WHERE SUBQUERY3_t1 . `col_int_key` > table3 . `pk` AND SUBQUERY3_t1 . `pk` != table3 . `pk` ) ) AND ( table1 . `pk` > 116 AND table1 . `pk` < ( 116 + 175 ) OR table1 . `pk` IN (251) ) OR table1 . `col_int_nokey` = table1 . `col_int_nokey`
+GROUP BY field4, field6, field9, field10
+HAVING field10 = 'c'
+;
+field1 field2 field3 field4 field5 field6 field7 field8 field9 field10
+drop table t1,t2,t3,t4,t5;
+set @@optimizer_switch= default;
+#launchpad BUG#609043
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (19,NULL,6,'2004-08-20','2004-08-20','05:03:03','05:03:03','2007-04-19 00:19:53','2007-04-19 00:19:53','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'1900-01-01','1900-01-01','18:38:59','18:38:59','1900-01-01 00:00:00','1900-01-01 00:00:00','d','d');
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+CREATE TABLE `t3` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+CREATE TABLE `t4` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t4` VALUES (100,2,5,'2001-07-26','2001-07-26','11:49:25','11:49:25','2007-04-25 05:08:49','2007-04-25 05:08:49','f','f');
+SET @@optimizer_switch = 'subquery_cache=off';
+/* cache is off */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+COUNT( DISTINCT table2 .`col_int_key` ) (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) field10
+1 NULL d
+1 NULL f
+SET @@optimizer_switch = 'subquery_cache=on';
+/* cache is on */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+COUNT( DISTINCT table2 .`col_int_key` ) (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) field10
+1 NULL d
+1 NULL f
+drop table t1,t2,t3,t4;
+set @@optimizer_switch= default;
+#launchpad BUG#611625
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,'w');
+INSERT INTO `t1` VALUES (2,7,'m');
+INSERT INTO `t1` VALUES (3,9,'m');
+INSERT INTO `t1` VALUES (4,7,'k');
+INSERT INTO `t1` VALUES (5,4,'r');
+INSERT INTO `t1` VALUES (6,2,'t');
+INSERT INTO `t1` VALUES (7,6,'j');
+INSERT INTO `t1` VALUES (8,8,'u');
+INSERT INTO `t1` VALUES (9,NULL,'h');
+INSERT INTO `t1` VALUES (10,5,'o');
+INSERT INTO `t1` VALUES (11,NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,'k');
+INSERT INTO `t1` VALUES (13,188,'e');
+INSERT INTO `t1` VALUES (14,2,'n');
+INSERT INTO `t1` VALUES (15,1,'t');
+INSERT INTO `t1` VALUES (16,1,'c');
+INSERT INTO `t1` VALUES (17,0,'m');
+INSERT INTO `t1` VALUES (18,9,'y');
+INSERT INTO `t1` VALUES (19,NULL,'f');
+INSERT INTO `t1` VALUES (20,4,'d');
+CREATE TABLE `t3` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t3` VALUES (1,6,'r');
+INSERT INTO `t3` VALUES (2,8,'c');
+INSERT INTO `t3` VALUES (3,6,'o');
+INSERT INTO `t3` VALUES (4,6,'c');
+INSERT INTO `t3` VALUES (5,3,'d');
+INSERT INTO `t3` VALUES (6,9,'v');
+INSERT INTO `t3` VALUES (7,2,'m');
+INSERT INTO `t3` VALUES (8,1,'j');
+INSERT INTO `t3` VALUES (9,8,'f');
+INSERT INTO `t3` VALUES (10,0,'n');
+INSERT INTO `t3` VALUES (11,9,'z');
+INSERT INTO `t3` VALUES (12,8,'h');
+INSERT INTO `t3` VALUES (13,NULL,'q');
+INSERT INTO `t3` VALUES (14,0,'w');
+INSERT INTO `t3` VALUES (15,5,'z');
+INSERT INTO `t3` VALUES (16,1,'j');
+INSERT INTO `t3` VALUES (17,1,'a');
+INSERT INTO `t3` VALUES (18,6,'m');
+INSERT INTO `t3` VALUES (19,6,'n');
+INSERT INTO `t3` VALUES (20,1,'e');
+INSERT INTO `t3` VALUES (21,8,'u');
+INSERT INTO `t3` VALUES (22,1,'s');
+INSERT INTO `t3` VALUES (23,0,'u');
+INSERT INTO `t3` VALUES (24,4,'r');
+INSERT INTO `t3` VALUES (25,9,'g');
+INSERT INTO `t3` VALUES (26,8,'o');
+INSERT INTO `t3` VALUES (27,5,'w');
+INSERT INTO `t3` VALUES (28,9,'b');
+INSERT INTO `t3` VALUES (29,5,NULL);
+INSERT INTO `t3` VALUES (30,NULL,'y');
+INSERT INTO `t3` VALUES (31,NULL,'y');
+INSERT INTO `t3` VALUES (32,105,'u');
+INSERT INTO `t3` VALUES (33,0,'p');
+INSERT INTO `t3` VALUES (34,3,'s');
+INSERT INTO `t3` VALUES (35,1,'e');
+INSERT INTO `t3` VALUES (36,75,'d');
+INSERT INTO `t3` VALUES (37,9,'d');
+INSERT INTO `t3` VALUES (38,7,'c');
+INSERT INTO `t3` VALUES (39,NULL,'b');
+INSERT INTO `t3` VALUES (40,NULL,'t');
+INSERT INTO `t3` VALUES (41,4,NULL);
+INSERT INTO `t3` VALUES (42,0,'y');
+INSERT INTO `t3` VALUES (43,204,'c');
+INSERT INTO `t3` VALUES (44,0,'d');
+INSERT INTO `t3` VALUES (45,9,'x');
+INSERT INTO `t3` VALUES (46,8,'p');
+INSERT INTO `t3` VALUES (47,7,'e');
+INSERT INTO `t3` VALUES (48,8,'g');
+INSERT INTO `t3` VALUES (49,NULL,'x');
+INSERT INTO `t3` VALUES (50,6,'s');
+INSERT INTO `t3` VALUES (51,5,'e');
+INSERT INTO `t3` VALUES (52,2,'l');
+INSERT INTO `t3` VALUES (53,3,'p');
+INSERT INTO `t3` VALUES (54,7,'h');
+INSERT INTO `t3` VALUES (55,NULL,'m');
+INSERT INTO `t3` VALUES (56,145,'n');
+INSERT INTO `t3` VALUES (57,0,'v');
+INSERT INTO `t3` VALUES (58,1,'b');
+INSERT INTO `t3` VALUES (59,7,'x');
+INSERT INTO `t3` VALUES (60,3,'r');
+INSERT INTO `t3` VALUES (61,NULL,'t');
+INSERT INTO `t3` VALUES (62,2,'w');
+INSERT INTO `t3` VALUES (63,2,'w');
+INSERT INTO `t3` VALUES (64,2,'k');
+INSERT INTO `t3` VALUES (65,8,'a');
+INSERT INTO `t3` VALUES (66,6,'t');
+INSERT INTO `t3` VALUES (67,1,'z');
+INSERT INTO `t3` VALUES (68,NULL,'e');
+INSERT INTO `t3` VALUES (69,1,'q');
+INSERT INTO `t3` VALUES (70,0,'e');
+INSERT INTO `t3` VALUES (71,4,'v');
+INSERT INTO `t3` VALUES (72,1,'d');
+INSERT INTO `t3` VALUES (73,1,'u');
+INSERT INTO `t3` VALUES (74,27,'o');
+INSERT INTO `t3` VALUES (75,4,'b');
+INSERT INTO `t3` VALUES (76,6,'c');
+INSERT INTO `t3` VALUES (77,2,'q');
+INSERT INTO `t3` VALUES (78,248,NULL);
+INSERT INTO `t3` VALUES (79,NULL,'h');
+INSERT INTO `t3` VALUES (80,9,'d');
+INSERT INTO `t3` VALUES (81,75,'w');
+INSERT INTO `t3` VALUES (82,2,'m');
+INSERT INTO `t3` VALUES (83,9,'i');
+INSERT INTO `t3` VALUES (84,4,'w');
+INSERT INTO `t3` VALUES (85,0,'f');
+INSERT INTO `t3` VALUES (86,0,'k');
+INSERT INTO `t3` VALUES (87,1,'v');
+INSERT INTO `t3` VALUES (88,119,'c');
+INSERT INTO `t3` VALUES (89,1,'y');
+INSERT INTO `t3` VALUES (90,7,'h');
+INSERT INTO `t3` VALUES (91,2,NULL);
+INSERT INTO `t3` VALUES (92,7,'t');
+INSERT INTO `t3` VALUES (93,2,'l');
+INSERT INTO `t3` VALUES (94,6,'a');
+INSERT INTO `t3` VALUES (95,4,'r');
+INSERT INTO `t3` VALUES (96,5,'s');
+INSERT INTO `t3` VALUES (97,7,'z');
+INSERT INTO `t3` VALUES (98,1,'j');
+INSERT INTO `t3` VALUES (99,7,'c');
+INSERT INTO `t3` VALUES (100,2,'f');
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,8,NULL);
+set optimizer_switch='subquery_cache=off';
+SELECT (
+SELECT `col_int_nokey`
+FROM t3
+WHERE table1 .`col_varchar_nokey` ) field13
+FROM t2 table1 JOIN t1 table2 ON table2 .`pk`
+ORDER BY field13;
+field13
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+set optimizer_switch='subquery_cache=on';
+SELECT
+(SELECT `col_int_nokey`
+ FROM t3
+WHERE table1 .`col_varchar_nokey` ) field13
+FROM t2 table1 JOIN t1 table2 ON table2 .`pk`
+ORDER BY field13;
+field13
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+drop table t1,t2,t3;
+set @@optimizer_switch= default;
+# LP BUG#615760 (part 1: double transformation)
+create table t1 (a int);
+insert into t1 values (1),(2);
+create table t2 (b int);
+insert into t2 values (1),(2);
+set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=on';
+explain extended
+select * from t1 where a in (select b from t2);
+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 t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` where (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`b`))))
+drop table t1,t2;
+set @@optimizer_switch= default;
+# LP BUG#615760 (part 2: incorrect heap table index flags)
+SET SESSION optimizer_switch = 'index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_condition_pushdown=off,firstmatch=off,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=on';
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+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,3,186,'m','m');
+INSERT INTO `t1` VALUES (14,6,NULL,'y','y');
+INSERT INTO `t1` VALUES (15,92,2,'j','j');
+INSERT INTO `t1` VALUES (16,7,3,'d','d');
+INSERT INTO `t1` VALUES (17,NULL,0,'z','z');
+INSERT INTO `t1` VALUES (18,3,133,'e','e');
+INSERT INTO `t1` VALUES (19,5,1,'h','h');
+INSERT INTO `t1` VALUES (20,1,8,'b','b');
+INSERT INTO `t1` VALUES (21,2,5,'s','s');
+INSERT INTO `t1` VALUES (22,NULL,5,'e','e');
+INSERT INTO `t1` VALUES (23,1,8,'j','j');
+INSERT INTO `t1` VALUES (24,0,6,'e','e');
+INSERT INTO `t1` VALUES (25,210,51,'f','f');
+INSERT INTO `t1` VALUES (26,8,4,'v','v');
+INSERT INTO `t1` VALUES (27,7,7,'x','x');
+INSERT INTO `t1` VALUES (28,5,6,'m','m');
+INSERT INTO `t1` VALUES (29,NULL,4,'c','c');
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (1,NULL,2,'w','w');
+INSERT INTO `t2` VALUES (2,7,9,'m','m');
+INSERT INTO `t2` VALUES (3,9,3,'m','m');
+INSERT INTO `t2` VALUES (4,7,9,'k','k');
+INSERT INTO `t2` VALUES (5,4,NULL,'r','r');
+INSERT INTO `t2` VALUES (6,2,9,'t','t');
+INSERT INTO `t2` VALUES (7,6,3,'j','j');
+INSERT INTO `t2` VALUES (8,8,8,'u','u');
+INSERT INTO `t2` VALUES (9,NULL,8,'h','h');
+INSERT INTO `t2` VALUES (10,5,53,'o','o');
+INSERT INTO `t2` VALUES (11,NULL,0,NULL,NULL);
+INSERT INTO `t2` VALUES (12,6,5,'k','k');
+INSERT INTO `t2` VALUES (13,188,166,'e','e');
+INSERT INTO `t2` VALUES (14,2,3,'n','n');
+INSERT INTO `t2` VALUES (15,1,0,'t','t');
+INSERT INTO `t2` VALUES (16,1,1,'c','c');
+INSERT INTO `t2` VALUES (17,0,9,'m','m');
+INSERT INTO `t2` VALUES (18,9,5,'y','y');
+INSERT INTO `t2` VALUES (19,NULL,6,'f','f');
+INSERT INTO `t2` VALUES (20,4,2,'d','d');
+SELECT table1 .`col_varchar_nokey`
+FROM t2 table1 RIGHT JOIN t1 LEFT JOIN (
+SELECT SUBQUERY1_t2 .*
+FROM t1 SUBQUERY1_t1 LEFT JOIN t2 SUBQUERY1_t2 ON SUBQUERY1_t2 .`col_int_key` = SUBQUERY1_t1 .`col_int_nokey` ) table3 STRAIGHT_JOIN ( (
+SELECT *
+FROM t1 ) table4 JOIN ( t1 table5 JOIN t2 table6 ON table5 .`pk` ) ON table5 .`col_varchar_nokey` ) ON table6 .`pk` = table5 .`col_int_key` ON table5 .`col_varchar_nokey` ON table5 .`col_varchar_key`
+WHERE table3 .`col_varchar_key` IN (
+SELECT `col_varchar_key`
+FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
+col_varchar_nokey
+drop table t1,t2;
+set @@optimizer_switch= default;
+# LP BUG#615378 (incorrect NULL result returning in Item_cache)
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_varchar_key` (`col_varchar_key`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (10,'v');
+INSERT INTO `t1` VALUES (11,'r');
+CREATE TABLE `t2` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_varchar_key` (`col_varchar_key`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (1,'r');
+INSERT INTO `t2` VALUES (2,'c');
+CREATE TABLE `t3` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_varchar_key` (`col_varchar_key`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `t3` VALUES (1,'w');
+SELECT SUM( DISTINCT table2 . `pk` ) AS field2 ,
+(SELECT SUM( SUBQUERY1_t2 . `pk` ) AS SUBQUERY1_field1
+FROM t2 AS SUBQUERY1_t2 STRAIGHT_JOIN
+t3 AS SUBQUERY1_t3 ON (SUBQUERY1_t3 . `pk` = SUBQUERY1_t2 . `pk` )
+WHERE table1 . `col_varchar_key` ) AS field3
+FROM ( t1 AS table1 LEFT JOIN
+( t2 AS table2 STRAIGHT_JOIN
+t3 AS table3 ON (table3 . `pk` = table2 . `pk` ) )
+ON (table3 . `col_varchar_key` = table1 . `col_varchar_key` ) )
+WHERE ( table1 . `pk` < 5 ) OR ( table1 . `col_varchar_key` IS NOT NULL)
+GROUP BY field3
+HAVING (field3 <= 'h' AND field2 != 4) ;
+field2 field3
+drop tables t1, t2, t3;
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
new file mode 100644
index 00000000000..dab00e3be19
--- /dev/null
+++ b/mysql-test/r/subselect_mat.result
@@ -0,0 +1,1346 @@
+drop table if exists t1, t2, t3, t1i, t2i, t3i;
+drop view if exists v1, v2, v1m, v2m;
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+create table t3 (c1 char(8), c2 char(8));
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 03', '2 - 03');
+insert into t3 values ('1 - 01', '2 - 01');
+insert into t3 values ('1 - 02', '2 - 02');
+insert into t3 values ('1 - 03', '2 - 03');
+insert into t3 values ('1 - 04', '2 - 04');
+create table t1i (a1 char(8), a2 char(8));
+create table t2i (b1 char(8), b2 char(8));
+create table t3i (c1 char(8), c2 char(8));
+create index it1i1 on t1i (a1);
+create index it1i2 on t1i (a2);
+create index it1i3 on t1i (a1, a2);
+create index it2i1 on t2i (b1);
+create index it2i2 on t2i (b2);
+create index it2i3 on t2i (b1, b2);
+create index it3i1 on t3i (c1);
+create index it3i2 on t3i (c2);
+create index it3i3 on t3i (c1, c2);
+insert into t1i select * from t1;
+insert into t2i select * from t2;
+insert into t3i select * from t3;
+set @@optimizer_switch='semijoin=off';
+/******************************************************************************
+* Simple tests.
+******************************************************************************/
+# non-indexed nullable fields
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+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 <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` = `materialized subselect`.`b1`))))))
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows 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; Using filesort
+Warnings:
+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` = `materialized subselect`.`b1`))))))
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+id select_type table type possible_keys key key_len ref rows 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; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+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; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+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 it2i1,it2i3 it2i1 9 NULL 5 100.00 Using where; Using index
+Warnings:
+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` = `materialized subselect`.`b1`))))))
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+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 range it2i1,it2i3 it2i1 9 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+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` = `materialized subselect`.`b1`))))))
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+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 it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+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 range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`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
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+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 range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`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
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`max(b2)`))))))
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
+execute st1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
+prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st2;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+execute st2;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+1 - 02 2 - 02
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+set @@optimizer_switch='default,semijoin=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch='default,materialization=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch='default,semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch='default,materialization=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch='default,semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch='default,materialization=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch='default,semijoin=off';
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`))))))
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+2 SUBQUERY t2i index NULL it2i3 18 NULL 5 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+/******************************************************************************
+* Views, UNIONs, several levels of nesting.
+******************************************************************************/
+# materialize the result of subquery over temp-table view
+create algorithm=merge view v1 as
+select b1, c2 from t2, t3 where b2 > c2;
+create algorithm=merge view v2 as
+select b1, c2 from t2, t3 group by b2, c2;
+Warnings:
+Warning 1354 View merge algorithm can't be used here for now (assumed undefined algorithm)
+create algorithm=temptable view v1m as
+select b1, c2 from t2, t3 where b2 > c2;
+create algorithm=temptable view v2m as
+select b1, c2 from t2, t3 group by b2, c2;
+select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+drop view v1, v2, v1m, v2m;
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+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
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3i
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+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
+3 SUBQUERY t3i index NULL it3i3 18 NULL 4 100.00 Using where; Using index
+4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3i`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`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
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 where c2 LIKE '%02') or
+b2 in (select c2 from t3 where c2 LIKE '%03')) and
+(a1, a2) in (select c1, c2 from t3
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+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
+5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+6 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
+4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`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` = `materialized subselect`.`c2`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+b2 in (select c2 from t3 where c2 LIKE '%03')) and
+(a1, a2) in (select c1, c2 from t3
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+a1 a2
+1 - 02 2 - 02
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 t3a where c1 = a1) or
+b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+(a1, a2) in (select c1, c2 from t3 t3c
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+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
+5 SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 SUBQUERY t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 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` = `materialized subselect`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3c`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+(a1, a2) in (select c1, c2 from t3 t3c
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+(select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 where c2 LIKE '%02') or
+b2 in (select c2 from t3 where c2 LIKE '%03')
+group by b1, b2) and
+(a1, a2) in (select c1, c2 from t3
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
+UNION
+(select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3i
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
+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
+5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+6 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; Using temporary; Using filesort
+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
+7 UNION t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+9 SUBQUERY t3i index NULL it3i3 18 NULL 4 100.00 Using where; Using index
+10 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+8 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
+NULL UNION RESULT <union1,7> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`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` = `materialized subselect`.`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` = `materialized subselect`.`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` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3i`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`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
+b2 in (select c2 from t3 where c2 LIKE '%03')
+group by b1, b2) and
+(a1, a2) in (select c1, c2 from t3
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
+UNION
+(select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3i
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
+a1 a2
+1 - 02 2 - 02
+1 - 01 2 - 01
+explain extended
+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
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+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
+4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`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
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+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
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
+a1 = c1;
+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
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`c1`) and (`test`.`t3`.`c2` = `materialized subselect`.`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
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
+a1 = c1;
+a1 a2 c1 c2
+1 - 01 2 - 01 1 - 01 2 - 01
+1 - 02 2 - 02 1 - 02 2 - 02
+/******************************************************************************
+* Negative tests, where materialization should not be applied.
+******************************************************************************/
+# UNION in a subquery
+explain extended
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+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 t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+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 <expr_cache><`test`.`t3`.`c1`>(<in_optimizer>(`test`.`t3`.`c1`,<exists>(select 1 from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select 1 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
+1 - 01 2 - 01
+1 - 02 2 - 02
+1 - 03 2 - 03
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 t3a where c1 = a1) or
+b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+(a1, a2) in (select c1, c2 from t3 t3c
+where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2));
+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
+5 DEPENDENT SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+6 DEPENDENT SUBQUERY t2i index_subquery it2i1,it2i2,it2i3 it2i3 18 func,func 2 100.00 Using index; Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 SUBQUERY t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+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 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 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` = `materialized subselect`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`))))))
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having ((<cache>(`test`.`t1`.`a1`) = '1 - 01') and (<cache>(`test`.`t1`.`a2`) = '2 - 01')))))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+a1 a2
+1 - 01 2 - 01
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having ((<cache>(`test`.`t1`.`a1`) = '1 - 01') and (<cache>(`test`.`t1`.`a2`) = '2 - 01')))))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+a1 a2
+1 - 01 2 - 01
+/******************************************************************************
+* Subqueries in other uncovered clauses.
+******************************************************************************/
+/* SELECT clause */
+select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
+((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL
+0
+0
+0
+/* GROUP BY clause */
+create table columns (col int key);
+insert into columns values (1), (2);
+explain extended
+select * from t1 group by (select col from columns limit 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY columns index NULL PRIMARY 4 NULL 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by (select `test`.`columns`.`col` from `test`.`columns` limit 1)
+select * from t1 group by (select col from columns limit 1);
+a1 a2
+1 - 00 2 - 00
+explain extended
+select * from t1 group by (a1 in (select col from columns));
+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 <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
+/* ORDER BY clause */
+explain extended
+select * from t1 order by (select col from columns limit 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY columns index NULL PRIMARY 4 NULL 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` order by (select `test`.`columns`.`col` from `test`.`columns` limit 1)
+select * from t1 order by (select col from columns limit 1);
+a1 a2
+1 - 00 2 - 00
+1 - 01 2 - 01
+1 - 02 2 - 02
+/******************************************************************************
+* Column types/sizes that affect materialization.
+******************************************************************************/
+/*
+Test that BLOBs are not materialized (except when arguments of some functions).
+*/
+# force materialization to be always considered
+set @@optimizer_switch='semijoin=off';
+set @prefix_len = 6;
+set @blob_len = 16;
+set @suffix_len = @blob_len - @prefix_len;
+create table t1_16 (a1 blob(16), a2 blob(16));
+create table t2_16 (b1 blob(16), b2 blob(16));
+create table t3_16 (c1 blob(16), c2 blob(16));
+insert into t1_16 values
+(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_16 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_16 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_16 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_16 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_16 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_16 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_16 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_16 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_16 values
+(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 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 Using where
+2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select 1 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');
+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_16
+where (a1,a2) in (select b1, b2 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 Using where
+2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a2`,`test`.`t1_16`.`a1`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 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_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 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 <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` = `materialized subselect`.`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');
+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_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+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 <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);
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+set @@group_concat_max_len = 256;
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+explain extended
+select * from t1
+where concat(a1,'x') IN
+(select left(a1,8) from t1_16
+where (a1, a2) IN
+(select t2_16.b1, t2_16.b2 from t2_16, t2
+where t2.b2 = substring(t2_16.b2,1,6) and
+t2.b1 IN (select c1 from t3 where c2 > '0')));
+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 t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 from `test`.`t1_16` where (<expr_cache><`test`.`t1_16`.`a2`,`test`.`t1_16`.`a1`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `materialized subselect`.`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;
+create table t1_512 (a1 blob(512), a2 blob(512));
+create table t2_512 (b1 blob(512), b2 blob(512));
+create table t3_512 (c1 blob(512), c2 blob(512));
+insert into t1_512 values
+(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_512 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_512 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_512 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_512 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_512 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_512 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_512 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_512 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_512 values
+(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 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 Using where
+2 DEPENDENT SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,<exists>(select 1 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');
+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_512
+where (a1,a2) in (select b1, b2 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 Using where
+2 DEPENDENT SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a2`,`test`.`t1_512`.`a1`>(<in_optimizer>((`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`),<exists>(select `test`.`t2_512`.`b1`,`test`.`t2_512`.`b2` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`) and (<cache>(`test`.`t1_512`.`a2`) = `test`.`t2_512`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 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_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 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 <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` = `materialized subselect`.`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');
+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_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+set @@group_concat_max_len = 256;
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+drop table t1_512, t2_512, t3_512;
+set @blob_len = 1024;
+set @suffix_len = @blob_len - @prefix_len;
+create table t1_1024 (a1 blob(1024), a2 blob(1024));
+create table t2_1024 (b1 blob(1024), b2 blob(1024));
+create table t3_1024 (c1 blob(1024), c2 blob(1024));
+insert into t1_1024 values
+(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_1024 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_1024 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1024 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_1024 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1024 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1024 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_1024 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_1024 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1024 values
+(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 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 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(select 1 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');
+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,a2) in (select b1, b2 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 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a2`,`test`.`t1_1024`.`a1`>(<in_optimizer>((`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`),<exists>(select `test`.`t2_1024`.`b1`,`test`.`t2_1024`.`b2` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`) and (<cache>(`test`.`t1_1024`.`a2`) = `test`.`t2_1024`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 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 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 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in (select 1 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');
+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);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+set @@group_concat_max_len = 256;
+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);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+drop table t1_1024, t2_1024, t3_1024;
+set @blob_len = 1025;
+set @suffix_len = @blob_len - @prefix_len;
+create table t1_1025 (a1 blob(1025), a2 blob(1025));
+create table t2_1025 (b1 blob(1025), b2 blob(1025));
+create table t3_1025 (c1 blob(1025), c2 blob(1025));
+insert into t1_1025 values
+(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_1025 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_1025 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1025 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_1025 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1025 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1025 values
+(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_1025 values
+(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_1025 values
+(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1025 values
+(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 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 Using where
+2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(select 1 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');
+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,a2) in (select b1, b2 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 Using where
+2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a2`,`test`.`t1_1025`.`a1`>(<in_optimizer>((`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`),<exists>(select `test`.`t2_1025`.`b1`,`test`.`t2_1025`.`b2` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`) and (<cache>(`test`.`t1_1025`.`a2`) = `test`.`t2_1025`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 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 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 Using where
+2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in (select 1 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');
+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);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+set @@group_concat_max_len = 256;
+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);
+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 <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` = `materialized subselect`.`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);
+left(a1,7) left(a2,7)
+drop table t1_1025, t2_1025, t3_1025;
+create table t1bit (a1 bit(3), a2 bit(3));
+create table t2bit (b1 bit(3), b2 bit(3));
+insert into t1bit values (b'000', b'100');
+insert into t1bit values (b'001', b'101');
+insert into t1bit values (b'010', b'110');
+insert into t2bit values (b'001', b'101');
+insert into t2bit values (b'010', b'110');
+insert into t2bit values (b'110', b'111');
+set @@optimizer_switch='semijoin=off';
+explain extended select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <expr_cache><`test`.`t1bit`.`a2`,`test`.`t1bit`.`a1`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1bit`.`a2` = `materialized subselect`.`b2`))))))
+select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+bin(a1) bin(a2)
+1 101
+10 110
+drop table t1bit, t2bit;
+create table t1bb (a1 bit(3), a2 blob(3));
+create table t2bb (b1 bit(3), b2 blob(3));
+insert into t1bb values (b'000', '100');
+insert into t1bb values (b'001', '101');
+insert into t1bb values (b'010', '110');
+insert into t2bb values (b'001', '101');
+insert into t2bb values (b'010', '110');
+insert into t2bb values (b'110', '111');
+explain extended select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1bb ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` where <expr_cache><`test`.`t1bb`.`a2`,`test`.`t1bb`.`a1`>(<in_optimizer>((`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`),<exists>(select `test`.`t2bb`.`b1`,`test`.`t2bb`.`b2` from `test`.`t2bb` where ((<cache>(`test`.`t1bb`.`a1`) = `test`.`t2bb`.`b1`) and (<cache>(`test`.`t1bb`.`a2`) = `test`.`t2bb`.`b2`)))))
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+bin(a1) a2
+1 101
+10 110
+drop table t1bb, t2bb;
+drop table t1, t2, t3, t1i, t2i, t3i, columns;
+/******************************************************************************
+* Test the cache of the left operand of IN.
+******************************************************************************/
+set @@optimizer_switch='semijoin=off';
+create table t1 (s1 int);
+create table t2 (s2 int);
+insert into t1 values (5),(1),(0);
+insert into t2 values (0), (1);
+select s2 from t2 where s2 in (select s1 from t1);
+s2
+0
+1
+drop table t1, t2;
+create table t1 (a int not null, b int not null);
+create table t2 (c int not null, d int not null);
+create table t3 (e int not null);
+insert into t1 values (1,10);
+insert into t1 values (1,20);
+insert into t1 values (2,10);
+insert into t1 values (2,20);
+insert into t1 values (2,30);
+insert into t1 values (3,20);
+insert into t1 values (4,40);
+insert into t2 values (2,10);
+insert into t2 values (2,20);
+insert into t2 values (2,40);
+insert into t2 values (3,20);
+insert into t2 values (4,10);
+insert into t2 values (5,10);
+insert into t3 values (10);
+insert into t3 values (10);
+insert into t3 values (20);
+insert into t3 values (30);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+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 <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` = `materialized subselect`.`c`))))))
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+create index it1a on t1(a);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+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 <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` = `materialized subselect`.`c`))))))
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+insert into t2 values (1,10);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+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 <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` = `materialized subselect`.`c`))))))
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+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 <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` = `materialized subselect`.`c`))))))
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+a
+2
+3
+create index iab on t1(a, b);
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+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 <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` = `materialized subselect`.`c`))))))
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+a
+2
+3
+explain extended
+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));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL iab 8 NULL 7 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
+select a from t1 group by a
+having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
+a
+2
+3
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL iab 8 NULL 7 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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 <expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select 1 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
+1
+2
+2
+2
+3
+drop table t1, t2, t3;
+create table t2 (a int, b int, key(a), key(b));
+insert into t2 values (3,3),(3,3),(3,3);
+select 1 from t2 where
+t2.a > 1
+or
+t2.a = 3 and not t2.a not in (select t2.b from t2);
+1
+1
+1
+1
+drop table t2;
+create table t1 (a1 int key);
+create table t2 (b1 int);
+insert into t1 values (5);
+explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+min(a1)
+set @@optimizer_switch='default,materialization=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+min(a1)
+set @@optimizer_switch='default,semijoin=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+set @@optimizer_switch='default,materialization=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+drop table t1,t2;
+create table t1 (a char(2), b varchar(10));
+insert into t1 values ('a', 'aaa');
+insert into t1 values ('aa', 'aaaa');
+set @@optimizer_switch='default,semijoin=off';
+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 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+select a,b from t1 where b in (select a from t1);
+a b
+prepare st1 from "select a,b from t1 where b in (select a from t1)";
+execute st1;
+a b
+execute st1;
+a b
+drop table t1;
+CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
+INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
+INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
+INSERT INTO t1 (f1, f2) VALUES (10, 1.668);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1, 1.789);
+INSERT INTO t2 VALUES (13, 1.454);
+SET @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+COUNT(*)
+2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk int,
+a varchar(1),
+b varchar(4),
+c varchar(4),
+d varchar(4),
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
+SET @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+pk
+2
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+pk
+2
+DROP TABLE t1, t2;
+#
+# BUG#50019: Wrong result for IN-subquery with materialization
+#
+create table t1(i int);
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+create table t2(i int);
+insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+create table t3(i int);
+insert into t3 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
+i
+1
+2
+3
+4
+set @save_optimizer_switch=@@optimizer_switch;
+set session optimizer_switch='materialization=off';
+select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
+i
+1
+2
+3
+4
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 3
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+select a, a in (select a from t1) from t0;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+update t1 set a=123;
+execute s;
+a a in (select a from t1)
+0 0
+1 0
+2 0
+drop table t0, t1;
+#
+# LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
+# partial_match_table_scan=on
+#
+create table t1 (c1 int);
+create table t2 (c2 int);
+insert into t1 values (1);
+insert into t2 values (2);
+set @@optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 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 system NULL NULL NULL NULL 1
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+c1_sum
+NULL
+EXPLAIN
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
+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 system NULL NULL NULL NULL 1
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
+c1_sum
+drop table t1, t2;
+#
+# BUG#52344 - Subquery materialization:
+# Assertion if subquery in on-clause of outer join
+#
+set @@optimizer_switch='semijoin=off';
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (10);
+CREATE TABLE t2 (j INTEGER);
+INSERT INTO t2 VALUES (5);
+CREATE TABLE t3 (k INTEGER);
+EXPLAIN
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
+i
+10
+EXPLAIN
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
+i
+10
+DROP TABLE t1, t2, t3;
+#
+# LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
+# partial_match_table_scan=on
+#
+CREATE TABLE t1 (c1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (c2 int);
+INSERT INTO t2 VALUES (10);
+PREPARE st1 FROM "
+SELECT *
+FROM t2 LEFT JOIN (SELECT * FROM t2) t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
+EXECUTE st1;
+c2 c2
+10 10
+EXECUTE st1;
+c2 c2
+10 10
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
new file mode 100644
index 00000000000..f2681412691
--- /dev/null
+++ b/mysql-test/r/subselect_no_mat.result
@@ -0,0 +1,4995 @@
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
+set optimizer_switch='materialization=off';
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><'1'>((select '1')) = 1)
+SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+1
+1
+SELECT (SELECT 1), a;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1;
+a
+1
+SELECT 1 FROM (SELECT (SELECT a) b) c;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id);
+id
+1
+SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 IN (SELECT 1);
+1 IN (SELECT 1)
+1
+SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
+1
+1
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1,2,3) = ROW(1,2,3);
+(SELECT 1,2,3) = ROW(1,2,3)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,1);
+(SELECT 1,2,3) = ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) < ROW(1,2,1);
+(SELECT 1,2,3) < ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) > ROW(1,2,1);
+(SELECT 1,2,3) > ROW(1,2,1)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
+(SELECT 1,2,3) = ROW(1,2,NULL)
+NULL
+SELECT ROW(1,2,3) = (SELECT 1,2,3);
+ROW(1,2,3) = (SELECT 1,2,3)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,1);
+ROW(1,2,3) = (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) < (SELECT 1,2,1);
+ROW(1,2,3) < (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) > (SELECT 1,2,1);
+ROW(1,2,3) > (SELECT 1,2,1)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
+ROW(1,2,3) = (SELECT 1,2,NULL)
+NULL
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
+1
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
+0
+SELECT (SELECT 1.5,2,'a') = ROW('1.5b',2,'b');
+(SELECT 1.5,2,'a') = ROW('1.5b',2,'b')
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1.5b'
+SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
+(SELECT 'b',2,'a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,'2','a');
+(SELECT 1.5,2,'a') = ROW(1.5,'2','a')
+1
+SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
+(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 as a,(SELECT a+a) b,(SELECT b);
+a b (SELECT b)
+1 2 2
+create table t1 (a int);
+create table t2 (a int, b int);
+create table t3 (a int);
+create table t4 (a int not null, b int not null);
+insert into t1 values (2);
+insert into t2 values (1,7),(2,7);
+insert into t4 values (4,8),(3,8),(5,9);
+select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;
+ERROR 42S22: Reference 'a1' not supported (forward reference in item list)
+select (select a from t1 where t1.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a) a
+NULL 1
+2 2
+select (select a from t1 where t1.a=t2.b), a from t2;
+(select a from t1 where t1.a=t2.b) a
+NULL 1
+NULL 2
+select (select a from t1), a, (select 1 union select 2 limit 1) from t2;
+(select a from t1) a (select 1 union select 2 limit 1)
+2 1 1
+2 2 1
+select (select a from t3), a from t2;
+(select a from t3) a
+NULL 1
+NULL 2
+select * from t2 where t2.a=(select a from t1);
+a b
+2 7
+insert into t3 values (6),(7),(3);
+select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
+a b
+1 7
+2 7
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+a b
+1 7
+2 7
+3 8
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+a b
+1 7
+2 7
+4 8
+3 8
+explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+3 UNION t4 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`)
+select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
+(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
+3 1
+7 2
+select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+(select t3.a from t3 where a<8 order by 1 desc limit 1) a
+7 2
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,'2' AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
+a
+select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
+8 7.5000
+8 4.5000
+9 7.5000
+explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select <expr_cache><`test`.`t2`.`a`>((select '2' from `test`.`t1` where ('2' = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`))) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
+ERROR 21000: Subquery returns more than 1 row
+create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
+create table t7( uq int primary key, name char(25));
+insert into t7 values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta");
+insert into t6 values (1,1),(1,2),(2,2),(1,3);
+select * from t6 where exists (select * from t7 where uq = clinic_uq);
+patient_uq clinic_uq
+1 1
+1 2
+2 2
+explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+Warnings:
+Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <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;
+CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
+INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
+CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0');
+INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2');
+CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00');
+INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13');
+SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
+a b
+W 1732-02-22
+SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
+a b
+W 1
+SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
+a b
+W a
+CREATE TABLE `t8` (
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+`email` varchar(60) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`),
+UNIQUE KEY `email` (`email`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
+INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
+INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
+EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
+Warnings:
+Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where 1
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using 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 (('1' = '1'))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b = (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <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);
+id
+2
+INSERT INTO t2 VALUES ((SELECT * FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+INSERT INTO t2 VALUES ((SELECT id FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+SELECT * FROM t2;
+id
+1
+2
+CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 values (1),(1);
+UPDATE t2 SET id=(SELECT * FROM t1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t2, t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2;
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 3 IN (SELECT * from t1);
+3 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+NULL
+select 1 > ALL (SELECT * from t1);
+1 > ALL (SELECT * from t1)
+0
+select 10 > ALL (SELECT * from t1);
+10 > ALL (SELECT * from t1)
+NULL
+select 1 > ANY (SELECT * from t1);
+1 > ANY (SELECT * from t1)
+NULL
+select 10 > ANY (SELECT * from t1);
+10 > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a varchar(20));
+insert into t1 values ('A'),('BC'),('DEF');
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a='BC';
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'DEF' IN (SELECT * from t1);
+'DEF' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+NULL
+select 'A' > ALL (SELECT * from t1);
+'A' > ALL (SELECT * from t1)
+0
+select 'XYZS' > ALL (SELECT * from t1);
+'XYZS' > ALL (SELECT * from t1)
+NULL
+select 'A' > ANY (SELECT * from t1);
+'A' > ANY (SELECT * from t1)
+NULL
+select 'XYZS' > ANY (SELECT * from t1);
+'XYZS' > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a float);
+insert into t1 values (1.5),(2.5),(3.5);
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2.5;
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 3.5 IN (SELECT * from t1);
+3.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+NULL
+select 1.5 > ALL (SELECT * from t1);
+1.5 > ALL (SELECT * from t1)
+0
+select 10.5 > ALL (SELECT * from t1);
+10.5 > ALL (SELECT * from t1)
+NULL
+select 1.5 > ANY (SELECT * from t1);
+1.5 > ANY (SELECT * from t1)
+NULL
+select 10.5 > ANY (SELECT * from t1);
+10.5 > ANY (SELECT * from t1)
+1
+explain extended select (select a+1) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (`test`.`t1`.`a` + 1) AS `(select a+1)` from `test`.`t1`
+select (select a+1) from t1;
+(select a+1)
+2.5
+NULL
+4.5
+drop table t1;
+CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
+CREATE TABLE t2 (a int(11) default '0', INDEX (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+a t1.a in (select t2.a from t2)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<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;
+a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using 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 1 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);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+drop table t1;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL auto_increment,
+SUB_ID int(3) unsigned NOT NULL default '0',
+REF_ID int(10) unsigned default NULL,
+REF_SUB int(3) unsigned default '0',
+PRIMARY KEY (ID,SUB_ID),
+UNIQUE KEY t1_PK (ID,SUB_ID),
+KEY t1_FK (REF_ID,REF_SUB),
+KEY t1_REFID (REF_ID)
+) ENGINE=MyISAM CHARSET=cp1251;
+INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
+SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
+REF_ID
+DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,0), (2,0), (3,0);
+insert into t2 values (1,1), (2,1), (3,1), (2,2);
+update ignore t1 set b=(select b from t2 where t1.a=t2.a);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+`email` varchar(60) NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `email` (`email`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM CHARSET=latin1 PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (id,pseudo,email) VALUES (1,'test','test'),(2,'test1','test1');
+SELECT pseudo as a, pseudo as b FROM t1 GROUP BY (SELECT a) ORDER BY (SELECT id*1);
+a b
+test test
+test1 test1
+drop table if exists t1;
+(SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0);
+a
+1
+create table t1 (a int not null, b int, primary key (a));
+create table t2 (a int not null, primary key (a));
+create table t3 (a int not null, b int, primary key (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+a
+2
+3
+explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
+drop table t1, t2, t3;
+create table t1 (a int, b int, index a (a,b));
+create table t2 (a int, index a (a));
+create table t3 (a int, b int, index a (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+a
+2
+3
+explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.61 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
+insert into t1 values (3,31);
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+3
+4
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+drop table t0, t1, t2, t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3 1
+2 2
+1 2
+drop table t1,t2,t3;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1);
+s1
+1
+drop table t1,t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
+ERROR 42S22: Unknown column 'x.s1' in 'field list'
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci,
+s2 CHAR(5) COLLATE latin1_swedish_ci);
+INSERT INTO t1 VALUES ('z','?');
+select * from t1 where s1 > (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+select * from t1 where s1 > any (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<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`,<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(<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(<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 t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`)))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where 1
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<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(<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');
+select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id text id text id text
+1 text1 1 text1 1 text1
+2 text2 2 text2 2 text2
+3 text3 3 text3 3 text3
+4 text4 4 text4 4 text4
+5 text5 5 text5 5 text5
+6 text6 6 text6 6 text6
+7 text7 7 text7 7 text7
+8 text8 8 text8 8 text8
+9 text9 9 text9 9 text9
+10 text10 10 text10 10 text10
+11 text11 11 text1 11 text11
+12 text12 12 text2 12 text12
+1000 text1000 NULL NULL 1000 text1000
+1001 text1001 NULL NULL 1000 text1000
+explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
+1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
+Warnings:
+Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
+drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (1);
+explain select benchmark(1000, (select a from t1 where a=sha(rand())));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
+drop table t1;
+create table t1(id int);
+create table t2(id int);
+create table t3(flag int);
+select (select * from t3 where id not null) from t1, t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
+drop table t1,t2,t3;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY id;
+id c
+1 1
+2 0
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+ALTER TABLE t1 ADD INDEX (a);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+a
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+a
+1
+2
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
+0-
+0-
+1-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
+1-
+0-
+0-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
+0-
+1-
+0-
+DROP TABLE t1;
+CREATE TABLE t1 ( a double, b double );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+DROP TABLE t1;
+CREATE TABLE t1 ( a char(1), b char(1));
+INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4);
+select * from t1 up where exists (select * from t1 where t1.a=up.a);
+a b
+1 2
+3 4
+explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <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);
+CREATE TABLE t2 (t2_a int, t2_b int, PRIMARY KEY (t2_a, t2_b));
+INSERT INTO t2 VALUES (1, 1), (1, 2);
+SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1
+HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a);
+t1_a t2_a t2_b
+1 1 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL);
+INSERT INTO t1 VALUES (1,'Tim'),(2,'Rebecca'),(3,NULL);
+CREATE TABLE t2 (id int(11) default NULL, pet varchar(10) default NULL);
+INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix');
+SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id;
+id name id pet
+1 Tim 1 Fido
+2 Rebecca 2 Spot
+3 NULL 3 Felix
+drop table t1,t2;
+CREATE TABLE t1 ( a int, b int );
+CREATE TABLE t2 ( c int, d int );
+INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+abc b
+1 2
+2 3
+3 4
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t2;
+c d
+1 2
+2 3
+3 4
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+deallocate prepare stmt1;
+select * from t2;
+c d
+1 2
+2 3
+3 4
+1 2
+2 3
+3 4
+drop table t3;
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+deallocate prepare stmt1;
+DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b));
+insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan');
+create table t2 (a int);
+insert into t2 values (1),(3),(2),(7);
+select a,b from t1 where match(b) against ('Ball') > 0;
+a b
+1 ball
+2 ball games
+select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
+a
+1
+2
+drop table t1,t2;
+CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin);
+CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel);
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000001','601','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000002','602','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000003','603','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000004','101','D0000000001','I0000000001');
+SELECT `IZAVORGANG_ID` FROM t1 WHERE `KUERZEL` IN(SELECT MIN(`KUERZEL`)`Feld1` FROM t1 WHERE `KUERZEL` LIKE'601%'And`IZAANALYSEART_ID`='D0000000001');
+IZAVORGANG_ID
+D0000000001
+drop table t1;
+CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+insert into t1 values (1,1),(1,2),(2,1),(2,2);
+insert into t2 values (1,2),(2,2);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop primary key;
+alter table t2 add key KEY1 (aid, bid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop key KEY1;
+alter table t2 add primary key (bid, aid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+drop table t1,t2;
+CREATE TABLE t1 (howmanyvalues bigint, avalue int);
+INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
+SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
+howmanyvalues count(*)
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 1
+3 1
+4 1
+drop table t1;
+create table t1 (x int);
+select (select b.x from t1 as b where b.x=a.x) from t1 as a where a.x=2 group by a.x;
+(select b.x from t1 as b where b.x=a.x)
+drop table t1;
+CREATE TABLE `t1` ( `master` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `slave` int(10) unsigned NOT NULL default '0', `access` int(10) unsigned NOT NULL default '0', UNIQUE KEY `access_u` (`master`,`map`,`slave`));
+INSERT INTO `t1` VALUES (1,0,0,700),(1,1,1,400),(1,5,5,400),(1,12,12,400),(1,12,32,400),(4,12,32,400);
+CREATE TABLE `t2` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`pid`,`map`), KEY `level` (`level`), KEY `id` (`id`,`map`)) ;
+INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'a'),(12,5,12,7,'a');
+SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ERROR 42S22: Unknown column 'b.sc' in 'field list'
+SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ac
+700
+NULL
+drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
+set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(1,2),(1,3),(2,4),(2,5);
+insert into t2 values (1,3),(2,1);
+select distinct a,b, (select max(b) from t2 where t1.b=t2.a) from t1 order by t1.b;
+a b (select max(b) from t2 where t1.b=t2.a)
+1 1 3
+1 2 1
+1 3 NULL
+2 4 NULL
+2 5 NULL
+drop table t1, t2;
+create table t1 (id int);
+create table t2 (id int, body text, fulltext (body));
+insert into t1 values(1),(2),(3);
+insert into t2 values (1,'test'), (2,'mysql'), (3,'test'), (4,'test');
+select count(distinct id) from t1 where id in (select id from t2 where match(body) against ('mysql' in boolean mode));
+count(distinct id)
+1
+drop table t2,t1;
+create table t1 (s1 int,s2 int);
+insert into t1 values (20,15);
+select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
+s1 s2
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (1),(null);
+select * from t1 where s1 < all (select s1 from t1);
+s1
+select s1, s1 < all (select s1 from t1) from t1;
+s1 s1 < all (select s1 from t1)
+1 0
+NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
+INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
+c
+Oceania
+drop table t1;
+create table t1 (a1 int);
+create table t2 (b1 int);
+select * from t1 where a2 > any(select b1 from t2);
+ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
+select * from t1 where a1 > any(select b1 from t2);
+a1
+drop table t1,t2;
+create table t1 (a integer, b integer);
+select (select * from t1) = (select 1,2);
+(select * from t1) = (select 1,2)
+NULL
+select (select 1,2) = (select * from t1);
+(select 1,2) = (select * from t1)
+NULL
+select row(1,2) = ANY (select * from t1);
+row(1,2) = ANY (select * from t1)
+0
+select row(1,2) != ALL (select * from t1);
+row(1,2) != ALL (select * from t1)
+1
+drop table t1;
+create table t1 (a integer, b integer);
+select row(1,(2,2)) in (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select row(1,(2,2)) = (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select (select * from t1) = row(1,(2,2));
+ERROR 21000: Operand should contain 1 column(s)
+drop table t1;
+create table t1 (a integer);
+insert into t1 values (1);
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
+xx 1 = ALL ( select 1 from t1 where 1 = xx )
+1 1
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+drop table t1;
+CREATE TABLE t1 (
+categoryId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+attributes text NOT NULL
+);
+INSERT INTO t1 VALUES (1,41,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(1,86,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(1,87,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,52,'2004-03-15','2004-10-01','2004-03-15','2004-09-17',''),
+(2,53,'2004-03-16','2004-10-01','2004-03-16','2004-09-17',''),
+(2,88,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,89,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(3,51,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(5,12,'2004-02-18','2010-01-01','2004-02-18','2004-02-18','');
+CREATE TABLE t2 (
+userId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+date datetime NOT NULL
+);
+INSERT INTO t2 VALUES (5141,71,'2003-11-18'),
+(5141,72,'2003-11-25'),(5141,41,'2004-08-06'),
+(5141,52,'2004-08-06'),(5141,53,'2004-08-06'),
+(5141,12,'2004-08-06'),(5141,86,'2004-10-21'),
+(5141,87,'2004-10-21'),(5141,88,'2004-10-21'),
+(5141,89,'2004-10-22'),(5141,51,'2004-10-26');
+CREATE TABLE t3 (
+groupId int(11) NOT NULL,
+parentId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+ordering int(11)
+);
+INSERT INTO t3 VALUES (12,9,'1000-01-01','3999-12-31','2004-01-29','2004-01-29',NULL);
+CREATE TABLE t4 (
+id int(11) NOT NULL,
+groupTypeId int(11) NOT NULL,
+groupKey varchar(50) NOT NULL,
+name text,
+ordering int(11),
+description text,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t4 VALUES (9,5,'stationer','stationer',0,'Stationer','2004-01-29','2004-01-29'),
+(12,5,'group2','group2',0,'group2','2004-01-29','2004-01-29');
+CREATE TABLE t5 (
+userId int(11) NOT NULL,
+groupId int(11) NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t5 VALUES (5141,12,'2004-08-06','2004-08-06');
+select
+count(distinct t2.userid) pass,
+groupstuff.*,
+count(t2.courseid) crse,
+t1.categoryid,
+t2.courseid,
+date_format(date, '%b%y') as colhead
+from t2
+join t1 on t2.courseid=t1.courseid
+join
+(
+select
+t5.userid,
+parentid,
+parentgroup,
+childid,
+groupname,
+grouptypeid
+from t5
+join
+(
+select t4.id as parentid,
+t4.name as parentgroup,
+t4.id as childid,
+t4.name as groupname,
+t4.grouptypeid
+from t4
+) as gin on t5.groupid=gin.childid
+) as groupstuff on t2.userid = groupstuff.userid
+group by
+groupstuff.groupname, colhead , t2.courseid;
+pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
+1 5141 12 group2 12 group2 5 1 5 12 Aug04
+1 5141 12 group2 12 group2 5 1 1 41 Aug04
+1 5141 12 group2 12 group2 5 1 2 52 Aug04
+1 5141 12 group2 12 group2 5 1 2 53 Aug04
+1 5141 12 group2 12 group2 5 1 3 51 Oct04
+1 5141 12 group2 12 group2 5 1 1 86 Oct04
+1 5141 12 group2 12 group2 5 1 1 87 Oct04
+1 5141 12 group2 12 group2 5 1 2 88 Oct04
+1 5141 12 group2 12 group2 5 1 2 89 Oct04
+drop table t1, t2, t3, t4, t5;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
+1
+1
+1
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2);
+insert into t2 values (0),(1),(2),(3);
+select a from t2 where a in (select a from t1);
+a
+1
+2
+select a from t2 having a in (select a from t1);
+a
+1
+2
+prepare stmt1 from "select a from t2 where a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+prepare stmt1 from "select a from t2 having a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+drop table t1, t2;
+create table t1 (a int, b int);
+insert into t1 values (1,2);
+select 1 = (select * from t1);
+ERROR 21000: Operand should contain 1 column(s)
+select (select * from t1) = 1;
+ERROR 21000: Operand should contain 2 column(s)
+select (1,2) = (select a from t1);
+ERROR 21000: Operand should contain 2 column(s)
+select (select a from t1) = (1,2);
+ERROR 21000: Operand should contain 1 column(s)
+select (1,2,3) = (select * from t1);
+ERROR 21000: Operand should contain 3 column(s)
+select (select * from t1) = (1,2,3);
+ERROR 21000: Operand should contain 2 column(s)
+drop table t1;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+INSERT INTO t2 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t2 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+insert into t2 values (null,null,'N');
+insert into t2 values (null,3,'0');
+insert into t2 values (null,5,'0');
+insert into t2 values (10,null,'0');
+insert into t1 values (10,3,'0');
+insert into t1 values (10,5,'0');
+insert into t1 values (10,10,'0');
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+one two
+5 6
+7 8
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`two` = `test`.`t1`.`two`) and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`flag` = 'N'))
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+2
+4
+1
+3
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+2
+1
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1 Using filesort
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'aa');
+INSERT INTO t1 VALUES ('a', 'aaa');
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE INDEX I1 ON t1 (a);
+CREATE INDEX I2 ON t1 (b);
+EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
+INSERT INTO t2 SELECT * FROM t1;
+CREATE INDEX I1 ON t2 (a);
+CREATE INDEX I2 ON t2 (b);
+EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2)
+SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+a b
+EXPLAIN
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+out_a MIN(b)
+1 2
+2 4
+DROP TABLE t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(f11 int, f12 int);
+create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
+insert into t1 values(1,1),(2,2), (3, 3);
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
+set session sort_buffer_size= 33*1024;
+select count(*) from t1 where f12 =
+(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
+count(*)
+3
+drop table t0,t1,t2;
+CREATE TABLE t4 (
+f7 varchar(32) collate utf8_bin NOT NULL default '',
+f10 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f7)
+);
+INSERT INTO t4 VALUES(1,1), (2,null);
+CREATE TABLE t2 (
+f4 varchar(32) collate utf8_bin NOT NULL default '',
+f2 varchar(50) collate utf8_bin default NULL,
+f3 varchar(10) collate utf8_bin default NULL,
+PRIMARY KEY (f4),
+UNIQUE KEY uk1 (f2)
+);
+INSERT INTO t2 VALUES(1,1,null), (2,2,null);
+CREATE TABLE t1 (
+f8 varchar(32) collate utf8_bin NOT NULL default '',
+f1 varchar(10) collate utf8_bin default NULL,
+f9 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f8)
+);
+INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
+CREATE TABLE t3 (
+f6 varchar(32) collate utf8_bin NOT NULL default '',
+f5 varchar(50) collate utf8_bin default NULL,
+PRIMARY KEY (f6)
+);
+INSERT INTO t3 VALUES (1,null), (2,null);
+SELECT
+IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
+IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
+SUM(
+IF(
+(SELECT VPC.f2
+FROM t2 VPC, t4 a2, t2 a3
+WHERE
+VPC.f4 = a2.f10 AND a3.f2 = a4
+LIMIT 1) IS NULL,
+0,
+t3.f5
+)
+) AS a6
+FROM
+t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
+GROUP BY a4;
+a4 f3 a6
+1 NULL NULL
+2 NULL NULL
+DROP TABLE t1, t2, t3, t4;
+create table t1 (a float(5,4) zerofill);
+create table t2 (a float(5,4),b float(2,0));
+select t1.a from t1 where
+t1.a= (select b from t2 limit 1) and not
+t1.a= (select a from t2 limit 1) ;
+a
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+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)))
+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 NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
+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))
+DROP TABLE t1;
+#
+# Bug#45061: Incorrectly market field caused wrong result.
+#
+CREATE TABLE `C` (
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+KEY `int_key` (`int_key`)
+);
+INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4),
+(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7),
+(5,2), (1,8), (7,0), (0,9), (9,5);
+SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+int_nokey int_key
+9 9
+0 0
+5 5
+0 0
+EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY C ALL NULL NULL NULL NULL 20 100.00 Using where
+DROP TABLE C;
+# End of test for bug#45061.
+#
+# Bug #46749: Segfault in add_key_fields() with outer subquery level
+# field references
+#
+CREATE TABLE t1 (
+a int,
+b int,
+UNIQUE (a), KEY (b)
+);
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE st1 like t1;
+INSERT INTO st1 VALUES (1,1), (2,1);
+CREATE TABLE st2 like t1;
+INSERT INTO st2 VALUES (1,1), (2,1);
+EXPLAIN
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+NULL 0
+DROP TABLE t1, st1, st2;
+#
+# Bug #48709: Assertion failed in sql_select.cc:11782:
+# int join_read_key(JOIN_TAB*)
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+# should have eq_ref for t1
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+x x outr ALL x x x x x x
+x x t1 eq_ref x x x x x x
+x x t2 index x x x x x x
+# should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+pk int_key
+3 3
+7 3
+DROP TABLE t1,t2;
+End of 5.0 tests.
+create table t_out (subcase char(3),
+a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+insert into t_out values ('A.1','2a', NULL, '2a');
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+
+Test general IN semantics (not top-level)
+
+case A.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+subcase pred_in pred_not_in
+A.1 0 1
+case A.2 - impossible
+case A.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+subcase pred_in pred_not_in
+A.3 NULL NULL
+case A.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+subcase pred_in pred_not_in
+A.4 0 1
+case B.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+subcase pred_in pred_not_in
+B.1 0 1
+case B.2
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+subcase pred_in pred_not_in
+B.2 1 0
+case B.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+subcase pred_in pred_not_in
+B.3 NULL NULL
+case B.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+subcase pred_in pred_not_in
+B.4 0 1
+
+Test IN as top-level predicate, and
+as non-top level for cases A.3, B.3 (the only cases with NULL result).
+
+case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+drop table t_out;
+drop table t_in;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (s1 CHAR(1));
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
+s1
+a
+DROP TABLE t1;
+CREATE TABLE t1(c INT, KEY(c));
+CREATE TABLE t2(a INT, b INT);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(pk INT PRIMARY KEY, a INT, INDEX idx(a));
+INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
+CREATE TABLE t2(pk INT PRIMARY KEY, a INT, b INT, INDEX idxa(a));
+INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
+SELECT * FROM t1
+WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
+pk a
+1 10
+3 30
+2 20
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+End of 5.1 tests.
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+set optimizer_switch=default;
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
new file mode 100644
index 00000000000..fc9f3a8a030
--- /dev/null
+++ b/mysql-test/r/subselect_no_opts.result
@@ -0,0 +1,4989 @@
+set optimizer_switch='materialization=off,semijoin=off';
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><'1'>((select '1')) = 1)
+SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+1
+1
+SELECT (SELECT 1), a;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1;
+a
+1
+SELECT 1 FROM (SELECT (SELECT a) b) c;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id);
+id
+1
+SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 IN (SELECT 1);
+1 IN (SELECT 1)
+1
+SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
+1
+1
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1,2,3) = ROW(1,2,3);
+(SELECT 1,2,3) = ROW(1,2,3)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,1);
+(SELECT 1,2,3) = ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) < ROW(1,2,1);
+(SELECT 1,2,3) < ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) > ROW(1,2,1);
+(SELECT 1,2,3) > ROW(1,2,1)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
+(SELECT 1,2,3) = ROW(1,2,NULL)
+NULL
+SELECT ROW(1,2,3) = (SELECT 1,2,3);
+ROW(1,2,3) = (SELECT 1,2,3)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,1);
+ROW(1,2,3) = (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) < (SELECT 1,2,1);
+ROW(1,2,3) < (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) > (SELECT 1,2,1);
+ROW(1,2,3) > (SELECT 1,2,1)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
+ROW(1,2,3) = (SELECT 1,2,NULL)
+NULL
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
+1
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
+0
+SELECT (SELECT 1.5,2,'a') = ROW('1.5b',2,'b');
+(SELECT 1.5,2,'a') = ROW('1.5b',2,'b')
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1.5b'
+SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
+(SELECT 'b',2,'a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,'2','a');
+(SELECT 1.5,2,'a') = ROW(1.5,'2','a')
+1
+SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
+(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 as a,(SELECT a+a) b,(SELECT b);
+a b (SELECT b)
+1 2 2
+create table t1 (a int);
+create table t2 (a int, b int);
+create table t3 (a int);
+create table t4 (a int not null, b int not null);
+insert into t1 values (2);
+insert into t2 values (1,7),(2,7);
+insert into t4 values (4,8),(3,8),(5,9);
+select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;
+ERROR 42S22: Reference 'a1' not supported (forward reference in item list)
+select (select a from t1 where t1.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a) a
+NULL 1
+2 2
+select (select a from t1 where t1.a=t2.b), a from t2;
+(select a from t1 where t1.a=t2.b) a
+NULL 1
+NULL 2
+select (select a from t1), a, (select 1 union select 2 limit 1) from t2;
+(select a from t1) a (select 1 union select 2 limit 1)
+2 1 1
+2 2 1
+select (select a from t3), a from t2;
+(select a from t3) a
+NULL 1
+NULL 2
+select * from t2 where t2.a=(select a from t1);
+a b
+2 7
+insert into t3 values (6),(7),(3);
+select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
+a b
+1 7
+2 7
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+a b
+1 7
+2 7
+3 8
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+a b
+1 7
+2 7
+4 8
+3 8
+explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+3 UNION t4 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`)
+select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
+(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
+3 1
+7 2
+select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+(select t3.a from t3 where a<8 order by 1 desc limit 1) a
+7 2
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,'2' AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
+a
+select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
+8 7.5000
+8 4.5000
+9 7.5000
+explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select <expr_cache><`test`.`t2`.`a`>((select '2' from `test`.`t1` where ('2' = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`))) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
+ERROR 21000: Subquery returns more than 1 row
+create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
+create table t7( uq int primary key, name char(25));
+insert into t7 values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta");
+insert into t6 values (1,1),(1,2),(2,2),(1,3);
+select * from t6 where exists (select * from t7 where uq = clinic_uq);
+patient_uq clinic_uq
+1 1
+1 2
+2 2
+explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+Warnings:
+Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <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;
+CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
+INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
+CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0');
+INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2');
+CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00');
+INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13');
+SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
+a b
+W 1732-02-22
+SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
+a b
+W 1
+SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
+a b
+W a
+CREATE TABLE `t8` (
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+`email` varchar(60) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`),
+UNIQUE KEY `email` (`email`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
+INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
+INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
+EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
+Warnings:
+Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where 1
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using 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 (('1' = '1'))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b = (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <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);
+id
+2
+INSERT INTO t2 VALUES ((SELECT * FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+INSERT INTO t2 VALUES ((SELECT id FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+SELECT * FROM t2;
+id
+1
+2
+CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 values (1),(1);
+UPDATE t2 SET id=(SELECT * FROM t1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t2, t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2;
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 3 IN (SELECT * from t1);
+3 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+NULL
+select 1 > ALL (SELECT * from t1);
+1 > ALL (SELECT * from t1)
+0
+select 10 > ALL (SELECT * from t1);
+10 > ALL (SELECT * from t1)
+NULL
+select 1 > ANY (SELECT * from t1);
+1 > ANY (SELECT * from t1)
+NULL
+select 10 > ANY (SELECT * from t1);
+10 > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a varchar(20));
+insert into t1 values ('A'),('BC'),('DEF');
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a='BC';
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'DEF' IN (SELECT * from t1);
+'DEF' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+NULL
+select 'A' > ALL (SELECT * from t1);
+'A' > ALL (SELECT * from t1)
+0
+select 'XYZS' > ALL (SELECT * from t1);
+'XYZS' > ALL (SELECT * from t1)
+NULL
+select 'A' > ANY (SELECT * from t1);
+'A' > ANY (SELECT * from t1)
+NULL
+select 'XYZS' > ANY (SELECT * from t1);
+'XYZS' > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a float);
+insert into t1 values (1.5),(2.5),(3.5);
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2.5;
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 3.5 IN (SELECT * from t1);
+3.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+NULL
+select 1.5 > ALL (SELECT * from t1);
+1.5 > ALL (SELECT * from t1)
+0
+select 10.5 > ALL (SELECT * from t1);
+10.5 > ALL (SELECT * from t1)
+NULL
+select 1.5 > ANY (SELECT * from t1);
+1.5 > ANY (SELECT * from t1)
+NULL
+select 10.5 > ANY (SELECT * from t1);
+10.5 > ANY (SELECT * from t1)
+1
+explain extended select (select a+1) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (`test`.`t1`.`a` + 1) AS `(select a+1)` from `test`.`t1`
+select (select a+1) from t1;
+(select a+1)
+2.5
+NULL
+4.5
+drop table t1;
+CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
+CREATE TABLE t2 (a int(11) default '0', INDEX (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+a t1.a in (select t2.a from t2)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<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;
+a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using 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 1 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);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+drop table t1;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL auto_increment,
+SUB_ID int(3) unsigned NOT NULL default '0',
+REF_ID int(10) unsigned default NULL,
+REF_SUB int(3) unsigned default '0',
+PRIMARY KEY (ID,SUB_ID),
+UNIQUE KEY t1_PK (ID,SUB_ID),
+KEY t1_FK (REF_ID,REF_SUB),
+KEY t1_REFID (REF_ID)
+) ENGINE=MyISAM CHARSET=cp1251;
+INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
+SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
+REF_ID
+DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,0), (2,0), (3,0);
+insert into t2 values (1,1), (2,1), (3,1), (2,2);
+update ignore t1 set b=(select b from t2 where t1.a=t2.a);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+`email` varchar(60) NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `email` (`email`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM CHARSET=latin1 PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (id,pseudo,email) VALUES (1,'test','test'),(2,'test1','test1');
+SELECT pseudo as a, pseudo as b FROM t1 GROUP BY (SELECT a) ORDER BY (SELECT id*1);
+a b
+test test
+test1 test1
+drop table if exists t1;
+(SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0);
+a
+1
+create table t1 (a int not null, b int, primary key (a));
+create table t2 (a int not null, primary key (a));
+create table t3 (a int not null, b int, primary key (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
+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
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))))
+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
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 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));
+create table t3 (a int, b int, index a (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a))))
+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 1001 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))))
+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 1001 100.00 Using index
+2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 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
+2
+3
+4
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))))
+drop table t0, t1, t2, t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3 1
+2 2
+1 2
+drop table t1,t2,t3;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1);
+s1
+1
+drop table t1,t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
+ERROR 42S22: Unknown column 'x.s1' in 'field list'
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci,
+s2 CHAR(5) COLLATE latin1_swedish_ci);
+INSERT INTO t1 VALUES ('z','?');
+select * from t1 where s1 > (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+select * from t1 where s1 > any (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<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`,<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(<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(<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 t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`)))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where 1
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<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(<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');
+select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id text id text id text
+1 text1 1 text1 1 text1
+2 text2 2 text2 2 text2
+3 text3 3 text3 3 text3
+4 text4 4 text4 4 text4
+5 text5 5 text5 5 text5
+6 text6 6 text6 6 text6
+7 text7 7 text7 7 text7
+8 text8 8 text8 8 text8
+9 text9 9 text9 9 text9
+10 text10 10 text10 10 text10
+11 text11 11 text1 11 text11
+12 text12 12 text2 12 text12
+1000 text1000 NULL NULL 1000 text1000
+1001 text1001 NULL NULL 1000 text1000
+explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
+1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
+Warnings:
+Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
+drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (1);
+explain select benchmark(1000, (select a from t1 where a=sha(rand())));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
+drop table t1;
+create table t1(id int);
+create table t2(id int);
+create table t3(flag int);
+select (select * from t3 where id not null) from t1, t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
+drop table t1,t2,t3;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY id;
+id c
+1 1
+2 0
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+ALTER TABLE t1 ADD INDEX (a);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+a
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+a
+1
+2
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
+0-
+0-
+1-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
+1-
+0-
+0-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
+0-
+1-
+0-
+DROP TABLE t1;
+CREATE TABLE t1 ( a double, b double );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+DROP TABLE t1;
+CREATE TABLE t1 ( a char(1), b char(1));
+INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4);
+select * from t1 up where exists (select * from t1 where t1.a=up.a);
+a b
+1 2
+3 4
+explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <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);
+CREATE TABLE t2 (t2_a int, t2_b int, PRIMARY KEY (t2_a, t2_b));
+INSERT INTO t2 VALUES (1, 1), (1, 2);
+SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1
+HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a);
+t1_a t2_a t2_b
+1 1 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL);
+INSERT INTO t1 VALUES (1,'Tim'),(2,'Rebecca'),(3,NULL);
+CREATE TABLE t2 (id int(11) default NULL, pet varchar(10) default NULL);
+INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix');
+SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id;
+id name id pet
+1 Tim 1 Fido
+2 Rebecca 2 Spot
+3 NULL 3 Felix
+drop table t1,t2;
+CREATE TABLE t1 ( a int, b int );
+CREATE TABLE t2 ( c int, d int );
+INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+abc b
+1 2
+2 3
+3 4
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t2;
+c d
+1 2
+2 3
+3 4
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+deallocate prepare stmt1;
+select * from t2;
+c d
+1 2
+2 3
+3 4
+1 2
+2 3
+3 4
+drop table t3;
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+deallocate prepare stmt1;
+DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b));
+insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan');
+create table t2 (a int);
+insert into t2 values (1),(3),(2),(7);
+select a,b from t1 where match(b) against ('Ball') > 0;
+a b
+1 ball
+2 ball games
+select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
+a
+1
+2
+drop table t1,t2;
+CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin);
+CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel);
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000001','601','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000002','602','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000003','603','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000004','101','D0000000001','I0000000001');
+SELECT `IZAVORGANG_ID` FROM t1 WHERE `KUERZEL` IN(SELECT MIN(`KUERZEL`)`Feld1` FROM t1 WHERE `KUERZEL` LIKE'601%'And`IZAANALYSEART_ID`='D0000000001');
+IZAVORGANG_ID
+D0000000001
+drop table t1;
+CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+insert into t1 values (1,1),(1,2),(2,1),(2,2);
+insert into t2 values (1,2),(2,2);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop primary key;
+alter table t2 add key KEY1 (aid, bid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop key KEY1;
+alter table t2 add primary key (bid, aid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+drop table t1,t2;
+CREATE TABLE t1 (howmanyvalues bigint, avalue int);
+INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
+SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
+howmanyvalues count(*)
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 1
+3 1
+4 1
+drop table t1;
+create table t1 (x int);
+select (select b.x from t1 as b where b.x=a.x) from t1 as a where a.x=2 group by a.x;
+(select b.x from t1 as b where b.x=a.x)
+drop table t1;
+CREATE TABLE `t1` ( `master` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `slave` int(10) unsigned NOT NULL default '0', `access` int(10) unsigned NOT NULL default '0', UNIQUE KEY `access_u` (`master`,`map`,`slave`));
+INSERT INTO `t1` VALUES (1,0,0,700),(1,1,1,400),(1,5,5,400),(1,12,12,400),(1,12,32,400),(4,12,32,400);
+CREATE TABLE `t2` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`pid`,`map`), KEY `level` (`level`), KEY `id` (`id`,`map`)) ;
+INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'a'),(12,5,12,7,'a');
+SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ERROR 42S22: Unknown column 'b.sc' in 'field list'
+SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ac
+700
+NULL
+drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
+set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(1,2),(1,3),(2,4),(2,5);
+insert into t2 values (1,3),(2,1);
+select distinct a,b, (select max(b) from t2 where t1.b=t2.a) from t1 order by t1.b;
+a b (select max(b) from t2 where t1.b=t2.a)
+1 1 3
+1 2 1
+1 3 NULL
+2 4 NULL
+2 5 NULL
+drop table t1, t2;
+create table t1 (id int);
+create table t2 (id int, body text, fulltext (body));
+insert into t1 values(1),(2),(3);
+insert into t2 values (1,'test'), (2,'mysql'), (3,'test'), (4,'test');
+select count(distinct id) from t1 where id in (select id from t2 where match(body) against ('mysql' in boolean mode));
+count(distinct id)
+1
+drop table t2,t1;
+create table t1 (s1 int,s2 int);
+insert into t1 values (20,15);
+select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
+s1 s2
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (1),(null);
+select * from t1 where s1 < all (select s1 from t1);
+s1
+select s1, s1 < all (select s1 from t1) from t1;
+s1 s1 < all (select s1 from t1)
+1 0
+NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
+INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
+c
+Oceania
+drop table t1;
+create table t1 (a1 int);
+create table t2 (b1 int);
+select * from t1 where a2 > any(select b1 from t2);
+ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
+select * from t1 where a1 > any(select b1 from t2);
+a1
+drop table t1,t2;
+create table t1 (a integer, b integer);
+select (select * from t1) = (select 1,2);
+(select * from t1) = (select 1,2)
+NULL
+select (select 1,2) = (select * from t1);
+(select 1,2) = (select * from t1)
+NULL
+select row(1,2) = ANY (select * from t1);
+row(1,2) = ANY (select * from t1)
+0
+select row(1,2) != ALL (select * from t1);
+row(1,2) != ALL (select * from t1)
+1
+drop table t1;
+create table t1 (a integer, b integer);
+select row(1,(2,2)) in (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select row(1,(2,2)) = (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select (select * from t1) = row(1,(2,2));
+ERROR 21000: Operand should contain 1 column(s)
+drop table t1;
+create table t1 (a integer);
+insert into t1 values (1);
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
+xx 1 = ALL ( select 1 from t1 where 1 = xx )
+1 1
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+drop table t1;
+CREATE TABLE t1 (
+categoryId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+attributes text NOT NULL
+);
+INSERT INTO t1 VALUES (1,41,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(1,86,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(1,87,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,52,'2004-03-15','2004-10-01','2004-03-15','2004-09-17',''),
+(2,53,'2004-03-16','2004-10-01','2004-03-16','2004-09-17',''),
+(2,88,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,89,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(3,51,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(5,12,'2004-02-18','2010-01-01','2004-02-18','2004-02-18','');
+CREATE TABLE t2 (
+userId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+date datetime NOT NULL
+);
+INSERT INTO t2 VALUES (5141,71,'2003-11-18'),
+(5141,72,'2003-11-25'),(5141,41,'2004-08-06'),
+(5141,52,'2004-08-06'),(5141,53,'2004-08-06'),
+(5141,12,'2004-08-06'),(5141,86,'2004-10-21'),
+(5141,87,'2004-10-21'),(5141,88,'2004-10-21'),
+(5141,89,'2004-10-22'),(5141,51,'2004-10-26');
+CREATE TABLE t3 (
+groupId int(11) NOT NULL,
+parentId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+ordering int(11)
+);
+INSERT INTO t3 VALUES (12,9,'1000-01-01','3999-12-31','2004-01-29','2004-01-29',NULL);
+CREATE TABLE t4 (
+id int(11) NOT NULL,
+groupTypeId int(11) NOT NULL,
+groupKey varchar(50) NOT NULL,
+name text,
+ordering int(11),
+description text,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t4 VALUES (9,5,'stationer','stationer',0,'Stationer','2004-01-29','2004-01-29'),
+(12,5,'group2','group2',0,'group2','2004-01-29','2004-01-29');
+CREATE TABLE t5 (
+userId int(11) NOT NULL,
+groupId int(11) NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t5 VALUES (5141,12,'2004-08-06','2004-08-06');
+select
+count(distinct t2.userid) pass,
+groupstuff.*,
+count(t2.courseid) crse,
+t1.categoryid,
+t2.courseid,
+date_format(date, '%b%y') as colhead
+from t2
+join t1 on t2.courseid=t1.courseid
+join
+(
+select
+t5.userid,
+parentid,
+parentgroup,
+childid,
+groupname,
+grouptypeid
+from t5
+join
+(
+select t4.id as parentid,
+t4.name as parentgroup,
+t4.id as childid,
+t4.name as groupname,
+t4.grouptypeid
+from t4
+) as gin on t5.groupid=gin.childid
+) as groupstuff on t2.userid = groupstuff.userid
+group by
+groupstuff.groupname, colhead , t2.courseid;
+pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
+1 5141 12 group2 12 group2 5 1 5 12 Aug04
+1 5141 12 group2 12 group2 5 1 1 41 Aug04
+1 5141 12 group2 12 group2 5 1 2 52 Aug04
+1 5141 12 group2 12 group2 5 1 2 53 Aug04
+1 5141 12 group2 12 group2 5 1 3 51 Oct04
+1 5141 12 group2 12 group2 5 1 1 86 Oct04
+1 5141 12 group2 12 group2 5 1 1 87 Oct04
+1 5141 12 group2 12 group2 5 1 2 88 Oct04
+1 5141 12 group2 12 group2 5 1 2 89 Oct04
+drop table t1, t2, t3, t4, t5;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
+1
+1
+1
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2);
+insert into t2 values (0),(1),(2),(3);
+select a from t2 where a in (select a from t1);
+a
+1
+2
+select a from t2 having a in (select a from t1);
+a
+1
+2
+prepare stmt1 from "select a from t2 where a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+prepare stmt1 from "select a from t2 having a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+drop table t1, t2;
+create table t1 (a int, b int);
+insert into t1 values (1,2);
+select 1 = (select * from t1);
+ERROR 21000: Operand should contain 1 column(s)
+select (select * from t1) = 1;
+ERROR 21000: Operand should contain 2 column(s)
+select (1,2) = (select a from t1);
+ERROR 21000: Operand should contain 2 column(s)
+select (select a from t1) = (1,2);
+ERROR 21000: Operand should contain 1 column(s)
+select (1,2,3) = (select * from t1);
+ERROR 21000: Operand should contain 3 column(s)
+select (select * from t1) = (1,2,3);
+ERROR 21000: Operand should contain 2 column(s)
+drop table t1;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+INSERT INTO t2 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t2 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+insert into t2 values (null,null,'N');
+insert into t2 values (null,3,'0');
+insert into t2 values (null,5,'0');
+insert into t2 values (10,null,'0');
+insert into t1 values (10,3,'0');
+insert into t1 values (10,5,'0');
+insert into t1 values (10,10,'0');
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+one two
+5 6
+7 8
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`)))))
+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; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+2
+4
+1
+3
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+2
+1
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1 Using filesort
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'aa');
+INSERT INTO t1 VALUES ('a', 'aaa');
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE INDEX I1 ON t1 (a);
+CREATE INDEX I2 ON t1 (b);
+EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
+INSERT INTO t2 SELECT * FROM t1;
+CREATE INDEX I1 ON t2 (a);
+CREATE INDEX I2 ON t2 (b);
+EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 2 Using index; Using where
+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 2 Using index; Using where
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+out_a MIN(b)
+1 2
+2 4
+DROP TABLE t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(f11 int, f12 int);
+create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
+insert into t1 values(1,1),(2,2), (3, 3);
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
+set session sort_buffer_size= 33*1024;
+select count(*) from t1 where f12 =
+(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
+count(*)
+3
+drop table t0,t1,t2;
+CREATE TABLE t4 (
+f7 varchar(32) collate utf8_bin NOT NULL default '',
+f10 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f7)
+);
+INSERT INTO t4 VALUES(1,1), (2,null);
+CREATE TABLE t2 (
+f4 varchar(32) collate utf8_bin NOT NULL default '',
+f2 varchar(50) collate utf8_bin default NULL,
+f3 varchar(10) collate utf8_bin default NULL,
+PRIMARY KEY (f4),
+UNIQUE KEY uk1 (f2)
+);
+INSERT INTO t2 VALUES(1,1,null), (2,2,null);
+CREATE TABLE t1 (
+f8 varchar(32) collate utf8_bin NOT NULL default '',
+f1 varchar(10) collate utf8_bin default NULL,
+f9 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f8)
+);
+INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
+CREATE TABLE t3 (
+f6 varchar(32) collate utf8_bin NOT NULL default '',
+f5 varchar(50) collate utf8_bin default NULL,
+PRIMARY KEY (f6)
+);
+INSERT INTO t3 VALUES (1,null), (2,null);
+SELECT
+IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
+IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
+SUM(
+IF(
+(SELECT VPC.f2
+FROM t2 VPC, t4 a2, t2 a3
+WHERE
+VPC.f4 = a2.f10 AND a3.f2 = a4
+LIMIT 1) IS NULL,
+0,
+t3.f5
+)
+) AS a6
+FROM
+t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
+GROUP BY a4;
+a4 f3 a6
+1 NULL NULL
+2 NULL NULL
+DROP TABLE t1, t2, t3, t4;
+create table t1 (a float(5,4) zerofill);
+create table t2 (a float(5,4),b float(2,0));
+select t1.a from t1 where
+t1.a= (select b from t2 limit 1) and not
+t1.a= (select a from t2 limit 1) ;
+a
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+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)))
+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 NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
+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))
+DROP TABLE t1;
+#
+# Bug#45061: Incorrectly market field caused wrong result.
+#
+CREATE TABLE `C` (
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+KEY `int_key` (`int_key`)
+);
+INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4),
+(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7),
+(5,2), (1,8), (7,0), (0,9), (9,5);
+SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+int_nokey int_key
+9 9
+0 0
+5 5
+0 0
+EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY C ALL NULL NULL NULL NULL 20 100.00 Using where
+DROP TABLE C;
+# End of test for bug#45061.
+#
+# Bug #46749: Segfault in add_key_fields() with outer subquery level
+# field references
+#
+CREATE TABLE t1 (
+a int,
+b int,
+UNIQUE (a), KEY (b)
+);
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE st1 like t1;
+INSERT INTO st1 VALUES (1,1), (2,1);
+CREATE TABLE st2 like t1;
+INSERT INTO st2 VALUES (1,1), (2,1);
+EXPLAIN
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+NULL 0
+DROP TABLE t1, st1, st2;
+#
+# Bug #48709: Assertion failed in sql_select.cc:11782:
+# int join_read_key(JOIN_TAB*)
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+# should have eq_ref for t1
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+x x outr ALL x x x x x x
+x x t1 eq_ref x x x x x x
+x x t2 index x x x x x x
+# should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+pk int_key
+3 3
+7 3
+DROP TABLE t1,t2;
+End of 5.0 tests.
+create table t_out (subcase char(3),
+a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+insert into t_out values ('A.1','2a', NULL, '2a');
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+
+Test general IN semantics (not top-level)
+
+case A.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+subcase pred_in pred_not_in
+A.1 0 1
+case A.2 - impossible
+case A.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+subcase pred_in pred_not_in
+A.3 NULL NULL
+case A.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+subcase pred_in pred_not_in
+A.4 0 1
+case B.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+subcase pred_in pred_not_in
+B.1 0 1
+case B.2
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+subcase pred_in pred_not_in
+B.2 1 0
+case B.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+subcase pred_in pred_not_in
+B.3 NULL NULL
+case B.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+subcase pred_in pred_not_in
+B.4 0 1
+
+Test IN as top-level predicate, and
+as non-top level for cases A.3, B.3 (the only cases with NULL result).
+
+case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+drop table t_out;
+drop table t_in;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (s1 CHAR(1));
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
+s1
+a
+DROP TABLE t1;
+CREATE TABLE t1(c INT, KEY(c));
+CREATE TABLE t2(a INT, b INT);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(pk INT PRIMARY KEY, a INT, INDEX idx(a));
+INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
+CREATE TABLE t2(pk INT PRIMARY KEY, a INT, b INT, INDEX idxa(a));
+INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
+SELECT * FROM t1
+WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
+pk a
+1 10
+3 30
+2 20
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+End of 5.1 tests.
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+set optimizer_switch=default;
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
new file mode 100644
index 00000000000..7be1e339cbe
--- /dev/null
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -0,0 +1,4989 @@
+set optimizer_switch='semijoin=off';
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><'1'>((select '1')) = 1)
+SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+1
+1
+SELECT (SELECT 1), a;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1;
+a
+1
+SELECT 1 FROM (SELECT (SELECT a) b) c;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id);
+id
+1
+SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 IN (SELECT 1);
+1 IN (SELECT 1)
+1
+SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
+1
+1
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1,2,3) = ROW(1,2,3);
+(SELECT 1,2,3) = ROW(1,2,3)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,1);
+(SELECT 1,2,3) = ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) < ROW(1,2,1);
+(SELECT 1,2,3) < ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) > ROW(1,2,1);
+(SELECT 1,2,3) > ROW(1,2,1)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
+(SELECT 1,2,3) = ROW(1,2,NULL)
+NULL
+SELECT ROW(1,2,3) = (SELECT 1,2,3);
+ROW(1,2,3) = (SELECT 1,2,3)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,1);
+ROW(1,2,3) = (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) < (SELECT 1,2,1);
+ROW(1,2,3) < (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) > (SELECT 1,2,1);
+ROW(1,2,3) > (SELECT 1,2,1)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
+ROW(1,2,3) = (SELECT 1,2,NULL)
+NULL
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
+1
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
+0
+SELECT (SELECT 1.5,2,'a') = ROW('1.5b',2,'b');
+(SELECT 1.5,2,'a') = ROW('1.5b',2,'b')
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1.5b'
+SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
+(SELECT 'b',2,'a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,'2','a');
+(SELECT 1.5,2,'a') = ROW(1.5,'2','a')
+1
+SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
+(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 as a,(SELECT a+a) b,(SELECT b);
+a b (SELECT b)
+1 2 2
+create table t1 (a int);
+create table t2 (a int, b int);
+create table t3 (a int);
+create table t4 (a int not null, b int not null);
+insert into t1 values (2);
+insert into t2 values (1,7),(2,7);
+insert into t4 values (4,8),(3,8),(5,9);
+select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;
+ERROR 42S22: Reference 'a1' not supported (forward reference in item list)
+select (select a from t1 where t1.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a) a
+NULL 1
+2 2
+select (select a from t1 where t1.a=t2.b), a from t2;
+(select a from t1 where t1.a=t2.b) a
+NULL 1
+NULL 2
+select (select a from t1), a, (select 1 union select 2 limit 1) from t2;
+(select a from t1) a (select 1 union select 2 limit 1)
+2 1 1
+2 2 1
+select (select a from t3), a from t2;
+(select a from t3) a
+NULL 1
+NULL 2
+select * from t2 where t2.a=(select a from t1);
+a b
+2 7
+insert into t3 values (6),(7),(3);
+select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
+a b
+1 7
+2 7
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+a b
+1 7
+2 7
+3 8
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+a b
+1 7
+2 7
+4 8
+3 8
+explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+3 UNION t4 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`)
+select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
+(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
+3 1
+7 2
+select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+(select t3.a from t3 where a<8 order by 1 desc limit 1) a
+7 2
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,'2' AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
+a
+select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
+8 7.5000
+8 4.5000
+9 7.5000
+explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select <expr_cache><`test`.`t2`.`a`>((select '2' from `test`.`t1` where ('2' = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`))) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
+ERROR 21000: Subquery returns more than 1 row
+create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
+create table t7( uq int primary key, name char(25));
+insert into t7 values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta");
+insert into t6 values (1,1),(1,2),(2,2),(1,3);
+select * from t6 where exists (select * from t7 where uq = clinic_uq);
+patient_uq clinic_uq
+1 1
+1 2
+2 2
+explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+Warnings:
+Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <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;
+CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
+INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
+CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0');
+INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2');
+CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00');
+INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13');
+SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
+a b
+W 1732-02-22
+SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
+a b
+W 1
+SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
+a b
+W a
+CREATE TABLE `t8` (
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+`email` varchar(60) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`),
+UNIQUE KEY `email` (`email`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
+INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
+INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
+EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
+Warnings:
+Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where 1
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using 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 (('1' = '1'))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b = (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <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);
+id
+2
+INSERT INTO t2 VALUES ((SELECT * FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+INSERT INTO t2 VALUES ((SELECT id FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+SELECT * FROM t2;
+id
+1
+2
+CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 values (1),(1);
+UPDATE t2 SET id=(SELECT * FROM t1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t2, t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2;
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 3 IN (SELECT * from t1);
+3 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+NULL
+select 1 > ALL (SELECT * from t1);
+1 > ALL (SELECT * from t1)
+0
+select 10 > ALL (SELECT * from t1);
+10 > ALL (SELECT * from t1)
+NULL
+select 1 > ANY (SELECT * from t1);
+1 > ANY (SELECT * from t1)
+NULL
+select 10 > ANY (SELECT * from t1);
+10 > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a varchar(20));
+insert into t1 values ('A'),('BC'),('DEF');
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a='BC';
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'DEF' IN (SELECT * from t1);
+'DEF' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+NULL
+select 'A' > ALL (SELECT * from t1);
+'A' > ALL (SELECT * from t1)
+0
+select 'XYZS' > ALL (SELECT * from t1);
+'XYZS' > ALL (SELECT * from t1)
+NULL
+select 'A' > ANY (SELECT * from t1);
+'A' > ANY (SELECT * from t1)
+NULL
+select 'XYZS' > ANY (SELECT * from t1);
+'XYZS' > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a float);
+insert into t1 values (1.5),(2.5),(3.5);
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2.5;
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 3.5 IN (SELECT * from t1);
+3.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+NULL
+select 1.5 > ALL (SELECT * from t1);
+1.5 > ALL (SELECT * from t1)
+0
+select 10.5 > ALL (SELECT * from t1);
+10.5 > ALL (SELECT * from t1)
+NULL
+select 1.5 > ANY (SELECT * from t1);
+1.5 > ANY (SELECT * from t1)
+NULL
+select 10.5 > ANY (SELECT * from t1);
+10.5 > ANY (SELECT * from t1)
+1
+explain extended select (select a+1) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (`test`.`t1`.`a` + 1) AS `(select a+1)` from `test`.`t1`
+select (select a+1) from t1;
+(select a+1)
+2.5
+NULL
+4.5
+drop table t1;
+CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
+CREATE TABLE t2 (a int(11) default '0', INDEX (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+a t1.a in (select t2.a from t2)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<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;
+a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using 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 1 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);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+drop table t1;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL auto_increment,
+SUB_ID int(3) unsigned NOT NULL default '0',
+REF_ID int(10) unsigned default NULL,
+REF_SUB int(3) unsigned default '0',
+PRIMARY KEY (ID,SUB_ID),
+UNIQUE KEY t1_PK (ID,SUB_ID),
+KEY t1_FK (REF_ID,REF_SUB),
+KEY t1_REFID (REF_ID)
+) ENGINE=MyISAM CHARSET=cp1251;
+INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
+SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
+REF_ID
+DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,0), (2,0), (3,0);
+insert into t2 values (1,1), (2,1), (3,1), (2,2);
+update ignore t1 set b=(select b from t2 where t1.a=t2.a);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+`email` varchar(60) NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `email` (`email`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM CHARSET=latin1 PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (id,pseudo,email) VALUES (1,'test','test'),(2,'test1','test1');
+SELECT pseudo as a, pseudo as b FROM t1 GROUP BY (SELECT a) ORDER BY (SELECT id*1);
+a b
+test test
+test1 test1
+drop table if exists t1;
+(SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0);
+a
+1
+create table t1 (a int not null, b int, primary key (a));
+create table t2 (a int not null, primary key (a));
+create table t3 (a int not null, b int, primary key (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
+2 SUBQUERY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`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 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
+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 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`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));
+create table t3 (a int, b int, index a (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`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 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
+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 SUBQUERY t3 index a a 5 NULL 3 100.00 Using index
+2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
+insert into t1 values (3,31);
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+3
+4
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+2 SUBQUERY t1 index NULL a 10 NULL 10005 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
+drop table t0, t1, t2, t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3 1
+2 2
+1 2
+drop table t1,t2,t3;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1);
+s1
+1
+drop table t1,t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
+ERROR 42S22: Unknown column 'x.s1' in 'field list'
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci,
+s2 CHAR(5) COLLATE latin1_swedish_ci);
+INSERT INTO t1 VALUES ('z','?');
+select * from t1 where s1 > (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+select * from t1 where s1 > any (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<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`,<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(<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(<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 t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible 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 0
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`)))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where 1
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<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(<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');
+select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id text id text id text
+1 text1 1 text1 1 text1
+2 text2 2 text2 2 text2
+3 text3 3 text3 3 text3
+4 text4 4 text4 4 text4
+5 text5 5 text5 5 text5
+6 text6 6 text6 6 text6
+7 text7 7 text7 7 text7
+8 text8 8 text8 8 text8
+9 text9 9 text9 9 text9
+10 text10 10 text10 10 text10
+11 text11 11 text1 11 text11
+12 text12 12 text2 12 text12
+1000 text1000 NULL NULL 1000 text1000
+1001 text1001 NULL NULL 1000 text1000
+explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
+1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
+Warnings:
+Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
+drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (1);
+explain select benchmark(1000, (select a from t1 where a=sha(rand())));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
+drop table t1;
+create table t1(id int);
+create table t2(id int);
+create table t3(flag int);
+select (select * from t3 where id not null) from t1, t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
+drop table t1,t2,t3;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY id;
+id c
+1 1
+2 0
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+ALTER TABLE t1 ADD INDEX (a);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+a
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+a
+1
+2
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
+0-
+0-
+1-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
+1-
+0-
+0-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
+0-
+1-
+0-
+DROP TABLE t1;
+CREATE TABLE t1 ( a double, b double );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+DROP TABLE t1;
+CREATE TABLE t1 ( a char(1), b char(1));
+INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4);
+select * from t1 up where exists (select * from t1 where t1.a=up.a);
+a b
+1 2
+3 4
+explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <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);
+CREATE TABLE t2 (t2_a int, t2_b int, PRIMARY KEY (t2_a, t2_b));
+INSERT INTO t2 VALUES (1, 1), (1, 2);
+SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1
+HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a);
+t1_a t2_a t2_b
+1 1 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL);
+INSERT INTO t1 VALUES (1,'Tim'),(2,'Rebecca'),(3,NULL);
+CREATE TABLE t2 (id int(11) default NULL, pet varchar(10) default NULL);
+INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix');
+SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id;
+id name id pet
+1 Tim 1 Fido
+2 Rebecca 2 Spot
+3 NULL 3 Felix
+drop table t1,t2;
+CREATE TABLE t1 ( a int, b int );
+CREATE TABLE t2 ( c int, d int );
+INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+abc b
+1 2
+2 3
+3 4
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t2;
+c d
+1 2
+2 3
+3 4
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+deallocate prepare stmt1;
+select * from t2;
+c d
+1 2
+2 3
+3 4
+1 2
+2 3
+3 4
+drop table t3;
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+deallocate prepare stmt1;
+DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b));
+insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan');
+create table t2 (a int);
+insert into t2 values (1),(3),(2),(7);
+select a,b from t1 where match(b) against ('Ball') > 0;
+a b
+1 ball
+2 ball games
+select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
+a
+1
+2
+drop table t1,t2;
+CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin);
+CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel);
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000001','601','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000002','602','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000003','603','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000004','101','D0000000001','I0000000001');
+SELECT `IZAVORGANG_ID` FROM t1 WHERE `KUERZEL` IN(SELECT MIN(`KUERZEL`)`Feld1` FROM t1 WHERE `KUERZEL` LIKE'601%'And`IZAANALYSEART_ID`='D0000000001');
+IZAVORGANG_ID
+D0000000001
+drop table t1;
+CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+insert into t1 values (1,1),(1,2),(2,1),(2,2);
+insert into t2 values (1,2),(2,2);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop primary key;
+alter table t2 add key KEY1 (aid, bid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop key KEY1;
+alter table t2 add primary key (bid, aid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+drop table t1,t2;
+CREATE TABLE t1 (howmanyvalues bigint, avalue int);
+INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
+SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
+howmanyvalues count(*)
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 1
+3 1
+4 1
+drop table t1;
+create table t1 (x int);
+select (select b.x from t1 as b where b.x=a.x) from t1 as a where a.x=2 group by a.x;
+(select b.x from t1 as b where b.x=a.x)
+drop table t1;
+CREATE TABLE `t1` ( `master` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `slave` int(10) unsigned NOT NULL default '0', `access` int(10) unsigned NOT NULL default '0', UNIQUE KEY `access_u` (`master`,`map`,`slave`));
+INSERT INTO `t1` VALUES (1,0,0,700),(1,1,1,400),(1,5,5,400),(1,12,12,400),(1,12,32,400),(4,12,32,400);
+CREATE TABLE `t2` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`pid`,`map`), KEY `level` (`level`), KEY `id` (`id`,`map`)) ;
+INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'a'),(12,5,12,7,'a');
+SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ERROR 42S22: Unknown column 'b.sc' in 'field list'
+SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ac
+700
+NULL
+drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
+set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(1,2),(1,3),(2,4),(2,5);
+insert into t2 values (1,3),(2,1);
+select distinct a,b, (select max(b) from t2 where t1.b=t2.a) from t1 order by t1.b;
+a b (select max(b) from t2 where t1.b=t2.a)
+1 1 3
+1 2 1
+1 3 NULL
+2 4 NULL
+2 5 NULL
+drop table t1, t2;
+create table t1 (id int);
+create table t2 (id int, body text, fulltext (body));
+insert into t1 values(1),(2),(3);
+insert into t2 values (1,'test'), (2,'mysql'), (3,'test'), (4,'test');
+select count(distinct id) from t1 where id in (select id from t2 where match(body) against ('mysql' in boolean mode));
+count(distinct id)
+1
+drop table t2,t1;
+create table t1 (s1 int,s2 int);
+insert into t1 values (20,15);
+select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
+s1 s2
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (1),(null);
+select * from t1 where s1 < all (select s1 from t1);
+s1
+select s1, s1 < all (select s1 from t1) from t1;
+s1 s1 < all (select s1 from t1)
+1 0
+NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
+INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
+c
+Oceania
+drop table t1;
+create table t1 (a1 int);
+create table t2 (b1 int);
+select * from t1 where a2 > any(select b1 from t2);
+ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
+select * from t1 where a1 > any(select b1 from t2);
+a1
+drop table t1,t2;
+create table t1 (a integer, b integer);
+select (select * from t1) = (select 1,2);
+(select * from t1) = (select 1,2)
+NULL
+select (select 1,2) = (select * from t1);
+(select 1,2) = (select * from t1)
+NULL
+select row(1,2) = ANY (select * from t1);
+row(1,2) = ANY (select * from t1)
+0
+select row(1,2) != ALL (select * from t1);
+row(1,2) != ALL (select * from t1)
+1
+drop table t1;
+create table t1 (a integer, b integer);
+select row(1,(2,2)) in (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select row(1,(2,2)) = (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select (select * from t1) = row(1,(2,2));
+ERROR 21000: Operand should contain 1 column(s)
+drop table t1;
+create table t1 (a integer);
+insert into t1 values (1);
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
+xx 1 = ALL ( select 1 from t1 where 1 = xx )
+1 1
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+drop table t1;
+CREATE TABLE t1 (
+categoryId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+attributes text NOT NULL
+);
+INSERT INTO t1 VALUES (1,41,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(1,86,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(1,87,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,52,'2004-03-15','2004-10-01','2004-03-15','2004-09-17',''),
+(2,53,'2004-03-16','2004-10-01','2004-03-16','2004-09-17',''),
+(2,88,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,89,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(3,51,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(5,12,'2004-02-18','2010-01-01','2004-02-18','2004-02-18','');
+CREATE TABLE t2 (
+userId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+date datetime NOT NULL
+);
+INSERT INTO t2 VALUES (5141,71,'2003-11-18'),
+(5141,72,'2003-11-25'),(5141,41,'2004-08-06'),
+(5141,52,'2004-08-06'),(5141,53,'2004-08-06'),
+(5141,12,'2004-08-06'),(5141,86,'2004-10-21'),
+(5141,87,'2004-10-21'),(5141,88,'2004-10-21'),
+(5141,89,'2004-10-22'),(5141,51,'2004-10-26');
+CREATE TABLE t3 (
+groupId int(11) NOT NULL,
+parentId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+ordering int(11)
+);
+INSERT INTO t3 VALUES (12,9,'1000-01-01','3999-12-31','2004-01-29','2004-01-29',NULL);
+CREATE TABLE t4 (
+id int(11) NOT NULL,
+groupTypeId int(11) NOT NULL,
+groupKey varchar(50) NOT NULL,
+name text,
+ordering int(11),
+description text,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t4 VALUES (9,5,'stationer','stationer',0,'Stationer','2004-01-29','2004-01-29'),
+(12,5,'group2','group2',0,'group2','2004-01-29','2004-01-29');
+CREATE TABLE t5 (
+userId int(11) NOT NULL,
+groupId int(11) NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t5 VALUES (5141,12,'2004-08-06','2004-08-06');
+select
+count(distinct t2.userid) pass,
+groupstuff.*,
+count(t2.courseid) crse,
+t1.categoryid,
+t2.courseid,
+date_format(date, '%b%y') as colhead
+from t2
+join t1 on t2.courseid=t1.courseid
+join
+(
+select
+t5.userid,
+parentid,
+parentgroup,
+childid,
+groupname,
+grouptypeid
+from t5
+join
+(
+select t4.id as parentid,
+t4.name as parentgroup,
+t4.id as childid,
+t4.name as groupname,
+t4.grouptypeid
+from t4
+) as gin on t5.groupid=gin.childid
+) as groupstuff on t2.userid = groupstuff.userid
+group by
+groupstuff.groupname, colhead , t2.courseid;
+pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
+1 5141 12 group2 12 group2 5 1 5 12 Aug04
+1 5141 12 group2 12 group2 5 1 1 41 Aug04
+1 5141 12 group2 12 group2 5 1 2 52 Aug04
+1 5141 12 group2 12 group2 5 1 2 53 Aug04
+1 5141 12 group2 12 group2 5 1 3 51 Oct04
+1 5141 12 group2 12 group2 5 1 1 86 Oct04
+1 5141 12 group2 12 group2 5 1 1 87 Oct04
+1 5141 12 group2 12 group2 5 1 2 88 Oct04
+1 5141 12 group2 12 group2 5 1 2 89 Oct04
+drop table t1, t2, t3, t4, t5;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
+1
+1
+1
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2);
+insert into t2 values (0),(1),(2),(3);
+select a from t2 where a in (select a from t1);
+a
+1
+2
+select a from t2 having a in (select a from t1);
+a
+1
+2
+prepare stmt1 from "select a from t2 where a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+prepare stmt1 from "select a from t2 having a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+drop table t1, t2;
+create table t1 (a int, b int);
+insert into t1 values (1,2);
+select 1 = (select * from t1);
+ERROR 21000: Operand should contain 1 column(s)
+select (select * from t1) = 1;
+ERROR 21000: Operand should contain 2 column(s)
+select (1,2) = (select a from t1);
+ERROR 21000: Operand should contain 2 column(s)
+select (select a from t1) = (1,2);
+ERROR 21000: Operand should contain 1 column(s)
+select (1,2,3) = (select * from t1);
+ERROR 21000: Operand should contain 3 column(s)
+select (select * from t1) = (1,2,3);
+ERROR 21000: Operand should contain 2 column(s)
+drop table t1;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+INSERT INTO t2 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t2 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+insert into t2 values (null,null,'N');
+insert into t2 values (null,3,'0');
+insert into t2 values (null,5,'0');
+insert into t2 values (10,null,'0');
+insert into t1 values (10,3,'0');
+insert into t1 values (10,5,'0');
+insert into t1 values (10,10,'0');
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+one two
+5 6
+7 8
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+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 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),(`test`.`t1`.`one`,`test`.`t1`.`two`) in ( <materialize> (select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N') ), <primary_index_lookup>(`test`.`t1`.`one` in <temporary table> on distinct_key where ((`test`.`t1`.`one` = `materialized subselect`.`one`) and (`test`.`t1`.`two` = `materialized subselect`.`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; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+2
+4
+1
+3
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+2
+1
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'aa');
+INSERT INTO t1 VALUES ('a', 'aaa');
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE INDEX I1 ON t1 (a);
+CREATE INDEX I2 ON t1 (b);
+EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t1 index NULL I1 2 NULL 2 Using index
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
+INSERT INTO t2 SELECT * FROM t1;
+CREATE INDEX I1 ON t2 (a);
+CREATE INDEX I2 ON t2 (b);
+EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t2 index NULL I1 4 NULL 2 Using index
+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 SUBQUERY t1 index NULL I1 2 NULL 2 Using where; Using index
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+out_a MIN(b)
+1 2
+2 4
+DROP TABLE t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(f11 int, f12 int);
+create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
+insert into t1 values(1,1),(2,2), (3, 3);
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
+set session sort_buffer_size= 33*1024;
+select count(*) from t1 where f12 =
+(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
+count(*)
+3
+drop table t0,t1,t2;
+CREATE TABLE t4 (
+f7 varchar(32) collate utf8_bin NOT NULL default '',
+f10 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f7)
+);
+INSERT INTO t4 VALUES(1,1), (2,null);
+CREATE TABLE t2 (
+f4 varchar(32) collate utf8_bin NOT NULL default '',
+f2 varchar(50) collate utf8_bin default NULL,
+f3 varchar(10) collate utf8_bin default NULL,
+PRIMARY KEY (f4),
+UNIQUE KEY uk1 (f2)
+);
+INSERT INTO t2 VALUES(1,1,null), (2,2,null);
+CREATE TABLE t1 (
+f8 varchar(32) collate utf8_bin NOT NULL default '',
+f1 varchar(10) collate utf8_bin default NULL,
+f9 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f8)
+);
+INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
+CREATE TABLE t3 (
+f6 varchar(32) collate utf8_bin NOT NULL default '',
+f5 varchar(50) collate utf8_bin default NULL,
+PRIMARY KEY (f6)
+);
+INSERT INTO t3 VALUES (1,null), (2,null);
+SELECT
+IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
+IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
+SUM(
+IF(
+(SELECT VPC.f2
+FROM t2 VPC, t4 a2, t2 a3
+WHERE
+VPC.f4 = a2.f10 AND a3.f2 = a4
+LIMIT 1) IS NULL,
+0,
+t3.f5
+)
+) AS a6
+FROM
+t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
+GROUP BY a4;
+a4 f3 a6
+1 NULL NULL
+2 NULL NULL
+DROP TABLE t1, t2, t3, t4;
+create table t1 (a float(5,4) zerofill);
+create table t2 (a float(5,4),b float(2,0));
+select t1.a from t1 where
+t1.a= (select b from t2 limit 1) and not
+t1.a= (select a from t2 limit 1) ;
+a
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`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 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`))))))
+DROP TABLE t1;
+#
+# Bug#45061: Incorrectly market field caused wrong result.
+#
+CREATE TABLE `C` (
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+KEY `int_key` (`int_key`)
+);
+INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4),
+(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7),
+(5,2), (1,8), (7,0), (0,9), (9,5);
+SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+int_nokey int_key
+9 9
+0 0
+5 5
+0 0
+EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY C ALL NULL NULL NULL NULL 20 100.00 Using where
+DROP TABLE C;
+# End of test for bug#45061.
+#
+# Bug #46749: Segfault in add_key_fields() with outer subquery level
+# field references
+#
+CREATE TABLE t1 (
+a int,
+b int,
+UNIQUE (a), KEY (b)
+);
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE st1 like t1;
+INSERT INTO st1 VALUES (1,1), (2,1);
+CREATE TABLE st2 like t1;
+INSERT INTO st2 VALUES (1,1), (2,1);
+EXPLAIN
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+NULL 0
+DROP TABLE t1, st1, st2;
+#
+# Bug #48709: Assertion failed in sql_select.cc:11782:
+# int join_read_key(JOIN_TAB*)
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+# should have eq_ref for t1
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+x x outr ALL x x x x x x
+x x t1 eq_ref x x x x x x
+x x t2 index x x x x x x
+# should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+pk int_key
+3 3
+7 3
+DROP TABLE t1,t2;
+End of 5.0 tests.
+create table t_out (subcase char(3),
+a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+insert into t_out values ('A.1','2a', NULL, '2a');
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+
+Test general IN semantics (not top-level)
+
+case A.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+subcase pred_in pred_not_in
+A.1 0 1
+case A.2 - impossible
+case A.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+subcase pred_in pred_not_in
+A.3 NULL NULL
+case A.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+subcase pred_in pred_not_in
+A.4 0 1
+case B.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+subcase pred_in pred_not_in
+B.1 0 1
+case B.2
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+subcase pred_in pred_not_in
+B.2 1 0
+case B.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+subcase pred_in pred_not_in
+B.3 NULL NULL
+case B.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+subcase pred_in pred_not_in
+B.4 0 1
+
+Test IN as top-level predicate, and
+as non-top level for cases A.3, B.3 (the only cases with NULL result).
+
+case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+drop table t_out;
+drop table t_in;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (s1 CHAR(1));
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
+s1
+a
+DROP TABLE t1;
+CREATE TABLE t1(c INT, KEY(c));
+CREATE TABLE t2(a INT, b INT);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(pk INT PRIMARY KEY, a INT, INDEX idx(a));
+INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
+CREATE TABLE t2(pk INT PRIMARY KEY, a INT, b INT, INDEX idxa(a));
+INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
+SELECT * FROM t1
+WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
+pk a
+1 10
+3 30
+2 20
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+End of 5.1 tests.
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+set optimizer_switch=default;
diff --git a/mysql-test/r/subselect_notembedded.result b/mysql-test/r/subselect_notembedded.result
index 9ef8c492ee3..cbe5a44bbf8 100644
--- a/mysql-test/r/subselect_notembedded.result
+++ b/mysql-test/r/subselect_notembedded.result
@@ -1,6 +1,7 @@
purge master logs before (select adddate(current_timestamp(), interval -4 day));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select adddate(current_timestamp(), interval -4 day))' at line 1
purge master logs before adddate(current_timestamp(), interval -4 day);
+drop table if exists t1;
create table t1(a int,b int,key(a),key(b));
insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
(6,7),(7,4),(5,3);
diff --git a/mysql-test/r/subselect_nulls.result b/mysql-test/r/subselect_nulls.result
new file mode 100644
index 00000000000..1ae8c9f6237
--- /dev/null
+++ b/mysql-test/r/subselect_nulls.result
@@ -0,0 +1,114 @@
+drop table if exists x1;
+drop table if exists x2;
+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
+(10, 10, 10),
+(20, 20, 20),
+(21, 20, null),
+(30, null, 30),
+(40, 40, 40);
+insert into x2 values
+(10, 10, 10),
+(20, 20, 20),
+(21, 20, null),
+(30, null, 30);
+select *
+from x1
+where (d1, d2) in (select d1, d2
+from x2);
+k d1 d2
+10 10 10
+20 20 20
+select *
+from x1
+where (d1, d2) in (select d1, d2
+from x2) is true;
+k d1 d2
+10 10 10
+20 20 20
+select *
+from x1
+where (d1, d2) in (select d1, d2
+from x2) is false;
+k d1 d2
+40 40 40
+select *
+from x1
+where (d1, d2) in (select d1, d2
+from x2) is unknown;
+k d1 d2
+21 20 NULL
+30 NULL 30
+select *
+from x1
+where d1 in (select d1
+from x2
+where x1.d2=x2.d2);
+k d1 d2
+10 10 10
+20 20 20
+select *
+from x1
+where d1 in (select d1
+from x2
+where x1.d2=x2.d2) is true;
+k d1 d2
+10 10 10
+20 20 20
+select *
+from x1
+where d1 in (select d1
+from x2
+where x1.d2=x2.d2) is false;
+k d1 d2
+21 20 NULL
+40 40 40
+select *
+from x1
+where d1 in (select d1
+from x2
+where x1.d2=x2.d2) is unknown;
+k d1 d2
+30 NULL 30
+select *
+from x1
+where 1 in (select 1
+from x2
+where x1.d1=x2.d1 and x1.d2=x2.d2);
+k d1 d2
+10 10 10
+20 20 20
+select *
+from x1
+where 1 in (select 1
+from x2
+where x1.d1=x2.d1 and x1.d2=x2.d2) is true;
+k d1 d2
+10 10 10
+20 20 20
+select *
+from x1
+where 1 in (select 1
+from x2
+where x1.d1=x2.d1 and x1.d2=x2.d2) is false;
+k d1 d2
+21 20 NULL
+30 NULL 30
+40 40 40
+select *
+from x1
+where 1 in (select 1
+from x2
+where x1.d1=x2.d1 and x1.d2=x2.d2) is unknown;
+k d1 d2
+select *
+from x1
+where exists (select *
+from x2
+where x1.d1=x2.d1 and x1.d2=x2.d2);
+k d1 d2
+10 10 10
+20 20 20
+drop table x1;
+drop table x2;
diff --git a/mysql-test/r/subselect_partial_match.result b/mysql-test/r/subselect_partial_match.result
new file mode 100644
index 00000000000..13f002235da
--- /dev/null
+++ b/mysql-test/r/subselect_partial_match.result
@@ -0,0 +1,65 @@
+drop table if exists t1, t2;
+#
+# LP BUG#608744
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off";
+create table t1 (a1 char(1), a2 char(1));
+insert into t1 values (NULL, 'b');
+create table t2 (b1 char(1), b2 char(2));
+insert into t2 values ('a','b'), ('c', 'd');
+select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2);
+a1 a2
+drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# LP BUG#601156
+#
+CREATE TABLE t1 (a1 int DEFAULT NULL, a2 int DEFAULT NULL);
+INSERT INTO t1 VALUES (NULL,2);
+INSERT INTO t1 VALUES (4,NULL);
+CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL);
+INSERT INTO t2 VALUES (6,NULL);
+INSERT INTO t2 VALUES (NULL,0);
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 const row not found
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select NULL AS `a1`,NULL AS `a2` from (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ()))))) `table1`
+DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# LP BUG#613009 Crash in Ordered_key::get_field_idx
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off';
+create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL);
+insert into t1 values (NULL, 'a21'), (NULL, 'a22');
+explain select * from t1 where (a1, a2) not in (select a1, a2 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 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+select * from t1 where (a1, a2) not in (select a1, a2 from t1);
+a1 a2
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# LP BUG#680058 void Ordered_key::add_key(rownum_t):
+# Assertion `key_buff_elements && cur_key_idx < key_buff_elements' failed
+#
+create table t1 (f1 char(1), f2 char(1));
+insert into t1 values ('t', '0'), ('0', 't');
+create table t2 (f3 char(1), f4 char(1));
+insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y');
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
+select * from t1 where (f1, f2) not in (select * from t2);
+f1 f2
+0 t
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
new file mode 100644
index 00000000000..708f1d3f95d
--- /dev/null
+++ b/mysql-test/r/subselect_sj.result
@@ -0,0 +1,1122 @@
+drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
+set @save_optimizer_switch=@@optimizer_switch;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+create table t11(a int, b int);
+create table t10 (pk int, a int, primary key(pk));
+insert into t10 select a,a from t0;
+create table t12 like t10;
+insert into t12 select * from t10;
+Flattened because of dependency, t10=func(t1)
+explain select * from t1 where a in (select pk from t10);
+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 t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+select * from t1 where a in (select pk from t10);
+a b
+0 0
+1 1
+2 2
+A confluent case of dependency
+explain select * from t1 where a in (select a from t10 where pk=12);
+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
+select * from t1 where a in (select a from t10 where pk=12);
+a b
+explain select * from t1 where a in (select a from t10 where pk=9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t10 const PRIMARY PRIMARY 4 const 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+select * from t1 where a in (select a from t10 where pk=9);
+a b
+An empty table inside
+explain select * from t1 where a in (select a from t11);
+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
+select * from t1 where a in (select a from t11);
+a b
+explain select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+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 t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using index
+select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+a b
+0 0
+1 1
+2 2
+flattening a nested subquery
+explain select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+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 t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
+1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 Using index
+select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+a b
+0 0
+1 1
+2 2
+flattening subquery w/ several tables
+explain extended select * from t1 where a in (select t10.pk from t10, t12 where t12.pk=t10.a);
+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
+1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using where
+1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t10`.`pk` = `test`.`t1`.`a`) and (`test`.`t12`.`pk` = `test`.`t10`.`a`))
+subqueries within outer joins go into ON expr.
+explAin extended
+select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
+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
+1 PRIMARY A ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on((<in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))) And (`test`.`A`.`A` = `test`.`t1`.`A`))) where 1
+t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
+explAin extended
+select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
+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
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on((<in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))) And (`test`.`t2`.`A` = `test`.`t1`.`A`))) where 1
+we shouldn't flatten if we're going to get a join of > MAX_TABLES.
+explain select * from
+t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
+t1 s10, t1 s11, t1 s12, t1 s13, t1 s14,t1 s15,t1 s16,t1 s17,t1 s18,t1 s19,
+t1 s20, t1 s21, t1 s22, t1 s23, t1 s24,t1 s25,t1 s26,t1 s27,t1 s28,t1 s29,
+t1 s30, t1 s31, t1 s32, t1 s33, t1 s34,t1 s35,t1 s36,t1 s37,t1 s38,t1 s39,
+t1 s40, t1 s41, t1 s42, t1 s43, t1 s44,t1 s45,t1 s46,t1 s47,t1 s48,t1 s49
+where
+s00.a in (
+select m00.a from
+t1 m00, t1 m01, t1 m02, t1 m03, t1 m04,t1 m05,t1 m06,t1 m07,t1 m08,t1 m09,
+t1 m10, t1 m11, t1 m12, t1 m13, t1 m14,t1 m15,t1 m16,t1 m17,t1 m18,t1 m19
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY s00 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY s01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s02 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s03 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s04 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s05 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s06 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s07 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s08 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s09 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s10 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s11 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s12 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s13 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s14 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s15 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s16 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s17 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s18 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s19 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s20 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s21 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s22 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s23 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s24 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s25 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s26 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s27 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s28 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s29 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s30 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s31 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s32 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s33 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s34 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s35 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s36 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s37 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s38 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s39 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s40 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s41 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s42 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s43 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s44 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s45 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s46 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m00 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+select * from
+t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+where t1.a < 5;
+a b a b
+0 0 0 0
+1 1 1 1
+2 2 2 2
+prepare s1 from
+' select * from
+ t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+ where t1.a < 5';
+execute s1;
+a b a b
+0 0 0 0
+1 1 1 1
+2 2 2 2
+execute s1;
+a b a b
+0 0 0 0
+1 1 1 1
+2 2 2 2
+insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B;
+explain extended select * from t1 where a in (select pk from t10 where pk<3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3))
+drop table t0, t1, t2;
+drop table t10, t11, t12;
+
+Bug#37899: Wrongly checked optimization prerequisite caused failed
+assertion.
+
+CREATE TABLE t1 (
+`pk` int(11),
+`varchar_nokey` varchar(5)
+);
+INSERT INTO t1 VALUES
+(1,'qk'),(2,'j'),(3,'aew');
+SELECT *
+FROM t1
+WHERE varchar_nokey IN (
+SELECT
+varchar_nokey
+FROM
+t1
+) XOR pk = 30;
+pk varchar_nokey
+1 qk
+2 j
+3 aew
+drop table t1;
+#
+# BUG#41842: Semi-join materialization strategy crashes when the upper query has HAVING
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+int_nokey int(11) NOT NULL,
+time_key time NOT NULL,
+datetime_key datetime NOT NULL,
+datetime_nokey datetime NOT NULL,
+varchar_key varchar(1) NOT NULL,
+varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY time_key (time_key),
+KEY datetime_key (datetime_key),
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t1 VALUES
+(1,0, '00:16:10','2008-09-03 14:25:40','2008-09-03 14:25:40','h','h'),
+(2,7, '00:00:00','2001-01-13 00:00:00','2001-01-13 00:00:00','',''),
+(3,0, '00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(4,2, '16:29:24','2000-10-16 01:39:08','2000-10-16 01:39:08','w','w'),
+(5,1, '09:23:32','0000-00-00 00:00:00','0000-00-00 00:00:00','p','p'),
+(6,3, '00:00:00','2007-12-02 00:00:00','2007-12-02 00:00:00','o','o'),
+(7,3, '00:00:00','2008-09-11 00:00:00','2008-09-11 00:00:00','',''),
+(8,0, '13:59:04','0000-00-00 00:00:00','0000-00-00 00:00:00','s','s'),
+(9,7, '09:01:06','0000-00-00 00:00:00','0000-00-00 00:00:00','d','d'),
+(10,5,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','n','n'),
+(11,0,'21:06:46','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(12,2,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','',''),
+(13,6,'14:45:34','2003-07-28 02:34:08','2003-07-28 02:34:08','w','w'),
+(14,1,'15:04:12','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(15,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(16,0,'15:55:23','2004-03-17 00:32:27','2004-03-17 00:32:27','p','p'),
+(17,1,'16:30:00','2004-12-27 19:20:00','2004-12-27 19:20:00','d','d'),
+(18,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','h','h'),
+(19,0,'14:13:26','2008-11-09 05:53:48','2008-11-09 05:53:48','o','o'),
+(20,0,'00:00:00','2009-10-11 06:58:04','2009-10-11 06:58:04','k','k');
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+int_nokey int(11) NOT NULL,
+time_key time NOT NULL,
+datetime_key datetime NOT NULL,
+datetime_nokey datetime NOT NULL,
+varchar_key varchar(1) NOT NULL,
+varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY time_key (time_key),
+KEY datetime_key (datetime_key),
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(10,0,'19:39:13','0000-00-00 00:00:00','0000-00-00 00:00:00','g','g'),
+(11,8,'03:43:53','0000-00-00 00:00:00','0000-00-00 00:00:00','b','b');
+SELECT OUTR.datetime_nokey AS X FROM t1 AS OUTR
+WHERE
+OUTR.varchar_nokey IN (SELECT
+INNR . varchar_nokey AS Y
+FROM t2 AS INNR
+WHERE
+INNR . datetime_key >= INNR . time_key OR
+INNR . pk = INNR . int_nokey
+)
+AND OUTR . varchar_nokey <= 'w'
+HAVING X > '2012-12-12';
+X
+drop table t1, t2;
+#
+# Bug#45191: Incorrectly initialized semi-join led to a wrong result.
+#
+CREATE TABLE STAFF (EMPNUM CHAR(3) NOT NULL,
+EMPNAME CHAR(20), GRADE DECIMAL(4), CITY CHAR(15));
+CREATE TABLE PROJ (PNUM CHAR(3) NOT NULL,
+PNAME CHAR(20), PTYPE CHAR(6),
+BUDGET DECIMAL(9),
+CITY CHAR(15));
+CREATE TABLE WORKS (EMPNUM CHAR(3) NOT NULL,
+PNUM CHAR(3) NOT NULL, HOURS DECIMAL(5));
+INSERT INTO STAFF VALUES ('E1','Alice',12,'Deale');
+INSERT INTO STAFF VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO STAFF VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO STAFF VALUES ('E4','Don',12,'Deale');
+INSERT INTO STAFF VALUES ('E5','Ed',13,'Akron');
+INSERT INTO PROJ VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO PROJ VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO PROJ VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO PROJ VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO PROJ VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO PROJ VALUES ('P6','PAYR','Design',50000,'Deale');
+INSERT INTO WORKS VALUES ('E1','P1',40);
+INSERT INTO WORKS VALUES ('E1','P2',20);
+INSERT INTO WORKS VALUES ('E1','P3',80);
+INSERT INTO WORKS VALUES ('E1','P4',20);
+INSERT INTO WORKS VALUES ('E1','P5',12);
+INSERT INTO WORKS VALUES ('E1','P6',12);
+INSERT INTO WORKS VALUES ('E2','P1',40);
+INSERT INTO WORKS VALUES ('E2','P2',80);
+INSERT INTO WORKS VALUES ('E3','P2',20);
+INSERT INTO WORKS VALUES ('E4','P2',20);
+INSERT INTO WORKS VALUES ('E4','P4',40);
+INSERT INTO WORKS VALUES ('E4','P5',80);
+set optimizer_switch=@save_optimizer_switch;
+set optimizer_switch='materialization=off';
+explain SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+(SELECT EMPNUM FROM WORKS
+WHERE PNUM IN
+(SELECT PNUM FROM PROJ));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY STAFF ALL NULL NULL NULL NULL 5
+1 PRIMARY PROJ ALL NULL NULL NULL NULL 6
+1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; FirstMatch(STAFF)
+SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+(SELECT EMPNUM FROM WORKS
+WHERE PNUM IN
+(SELECT PNUM FROM PROJ));
+EMPNUM EMPNAME
+E1 Alice
+E2 Betty
+E3 Carmen
+E4 Don
+set optimizer_switch=@save_optimizer_switch;
+drop table STAFF,WORKS,PROJ;
+# End of bug#45191
+#
+# Bug#46550 Azalea returning duplicate results for some IN subqueries
+# w/ semijoin=on
+#
+DROP TABLE IF EXISTS t0, t1, t2;
+CREATE TABLE t0 (
+int_key int(11) DEFAULT NULL,
+varchar_key varchar(1) DEFAULT NULL,
+varchar_nokey varchar(1) DEFAULT NULL,
+KEY int_key (int_key),
+KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t0 VALUES
+(1,'m','m'),
+(40,'h','h'),
+(1,'r','r'),
+(1,'h','h'),
+(9,'x','x'),
+(NULL,'q','q'),
+(NULL,'k','k'),
+(7,'l','l'),
+(182,'k','k'),
+(202,'a','a'),
+(7,'x','x'),
+(6,'j','j'),
+(119,'z','z'),
+(4,'d','d'),
+(5,'h','h'),
+(1,'u','u'),
+(3,'q','q'),
+(7,'a','a'),
+(3,'e','e'),
+(6,'l','l');
+CREATE TABLE t1 (
+int_key int(11) DEFAULT NULL,
+varchar_key varchar(1) DEFAULT NULL,
+varchar_nokey varchar(1) DEFAULT NULL,
+KEY int_key (int_key),
+KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t1 VALUES (7,NULL,NULL),(4,'x','x');
+CREATE TABLE t2 (
+int_key int(11) DEFAULT NULL,
+varchar_key varchar(1) DEFAULT NULL,
+varchar_nokey varchar(1) DEFAULT NULL,
+KEY int_key (int_key),
+KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t2 VALUES (123,NULL,NULL);
+SELECT int_key
+FROM t0
+WHERE varchar_nokey IN (
+SELECT t1 .varchar_key from t1
+);
+int_key
+9
+7
+SELECT t0.int_key
+FROM t0
+WHERE t0.varchar_nokey IN (
+SELECT t1_1 .varchar_key
+FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+int_key
+9
+7
+SELECT t0.int_key
+FROM t0, t2
+WHERE t0.varchar_nokey IN (
+SELECT t1_1 .varchar_key
+FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+int_key
+9
+7
+DROP TABLE t0, t1, t2;
+# End of bug#46550
+#
+# Bug #46744 Crash in optimize_semijoin_nests on empty view
+# with limit and procedure.
+#
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE TABLE t1 ( f1 int );
+CREATE TABLE t2 ( f1 int );
+insert into t2 values (5), (7);
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
+create procedure p1()
+select COUNT(*)
+FROM v1 WHERE f1 IN
+(SELECT f1 FROM t2 WHERE f1 = ANY (SELECT f1 FROM v1));
+SET SESSION optimizer_switch = 'semijoin=on';
+CALL p1();
+COUNT(*)
+0
+SET SESSION optimizer_switch = 'semijoin=off';
+CALL p1();
+COUNT(*)
+0
+drop table t1, t2;
+drop view v1;
+drop procedure p1;
+set SESSION optimizer_switch=@save_optimizer_switch;
+# End of bug#46744
+
+Bug#46797 "Crash in fix_semijoin_strategies_for_picked_join_order
+with semijoin=on"
+
+CREATE TABLE t1 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+CREATE TABLE t2 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+CREATE TABLE t3 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+(NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+WHERE (varchar_key,varchar_key)
+IN (SELECT t1.varchar_key, t2 .varchar_key
+FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+)
+);
+varchar_key
+DROP TABLE t1, t2, t3;
+#
+# Bug#46556 Returning incorrect, empty results for some IN subqueries
+# w/semijoin=on
+#
+CREATE TABLE t0 (
+pk INTEGER,
+vkey VARCHAR(1),
+vnokey VARCHAR(1),
+PRIMARY KEY (pk),
+KEY vkey(vkey)
+);
+INSERT INTO t0
+VALUES (1,'g','g'), (2,'v','v'), (3,'t','t'), (4,'u','u'), (5,'n','n');
+EXPLAIN EXTENDED SELECT vkey FROM t0 WHERE pk IN
+(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t0 ALL PRIMARY NULL NULL NULL 5 100.00
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where
+1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`) and (`test`.`t1`.`pk` = `test`.`t0`.`pk`))
+SELECT vkey FROM t0 WHERE pk IN
+(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+vkey
+g
+v
+t
+u
+n
+DROP TABLE t0;
+# End of bug#46556
+
+Bug #48073 Subquery on char columns from view crashes Mysql
+
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+CREATE TABLE t1 (
+city VARCHAR(50) NOT NULL,
+country_id SMALLINT UNSIGNED NOT NULL
+);
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+CREATE TABLE t2 (
+country_id SMALLINT UNSIGNED NOT NULL,
+country VARCHAR(50) NOT NULL
+);
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'American Samoa') ;
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+SELECT country
+FROM t2
+WHERE LEFT(country, 1) = "A"
+);
+city country_id
+Algeria 2
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+SELECT country
+FROM v1
+);
+city country_id
+Algeria 2
+drop table t1, t2;
+drop view v1;
+# End of bug#48073
+
+Bug#48834: Procedure with view + subquery + semijoin=on
+crashes on second call.
+
+SET SESSION optimizer_switch ='semijoin=on';
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+CREATE VIEW v1 AS
+SELECT t1field as v1field
+FROM t1 A
+WHERE A.t1field IN (SELECT t1field FROM t2 );
+CREATE VIEW v2 AS
+SELECT t2field as v2field
+FROM t2 A
+WHERE A.t2field IN (SELECT t2field FROM t2 );
+CREATE PROCEDURE p1 ()
+BEGIN
+SELECT v1field
+FROM v1
+WHERE v1field IN ( SELECT v2field as vf_inner FROM v2 );
+END|
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+CALL p1;
+v1field
+2
+3
+CALL p1;
+v1field
+2
+3
+DROP TABLE t1,t2;
+DROP VIEW v1,v2;
+DROP PROCEDURE p1;
+set SESSION optimizer_switch=@save_optimizer_switch;
+# End of BUG#48834
+
+Bug#49097 subquery with view generates wrong result with
+non-prepared statement
+
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+CREATE TABLE t1 (
+city VARCHAR(50) NOT NULL,
+country_id SMALLINT UNSIGNED NOT NULL
+);
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+CREATE TABLE t2 (
+country_id SMALLINT UNSIGNED NOT NULL,
+country VARCHAR(50) NOT NULL
+);
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'XAmerican Samoa') ;
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+SELECT country_id
+FROM t2
+WHERE LEFT(country,1) = "A"
+);
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+SELECT country_id
+FROM v1
+);
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+PREPARE stmt FROM
+"
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM v1
+);
+";
+execute stmt;
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+deallocate prepare stmt;
+drop table t1, t2;
+drop view v1;
+# End of Bug#49097
+#
+# BUG#38075: Wrong result: rows matching a subquery with outer join not returned
+#
+DROP TABLE IF EXISTS ot1, it1, it2;
+CREATE TABLE it2 (
+int_key int(11) NOT NULL,
+datetime_key datetime NOT NULL,
+KEY int_key (int_key),
+KEY datetime_key (datetime_key)
+);
+INSERT INTO it2 VALUES
+(5,'2002-04-10 14:25:30'), (0,'0000-00-00 00:00:00'),
+(0,'2006-09-14 04:01:02'), (4,'0000-00-00 00:00:00'),
+(8,'0000-00-00 00:00:00'), (5,'0000-00-00 00:00:00'),
+(9,'0000-00-00 00:00:00'), (8,'2007-04-01 11:04:17'),
+(1,'0000-00-00 00:00:00'), (7,'2009-01-12 00:00:00'),
+(0,'2009-06-05 00:00:00'), (3,'2006-02-14 18:06:35'),
+(5,'2006-02-21 07:08:16'), (0,'0000-00-00 00:00:00'),
+(7,'0000-00-00 00:00:00'), (0,'0000-00-00 00:00:00'),
+(0,'2007-02-13 00:00:00'), (1,'0000-00-00 00:00:00'),
+(0,'0000-00-00 00:00:00'), (1,'2003-08-11 00:00:00');
+CREATE TABLE ot1 (
+int_nokey int(11) NOT NULL,
+int_key int(11) NOT NULL,
+KEY int_key (int_key)
+);
+INSERT INTO ot1 VALUES
+(5,0), (3,0), (0,2), (3,0), (1,3), (0,0), (1,7), (7,0), (1,7), (0,7),
+(0,9), (8,2), (4,4), (9,3), (0,9), (2,5), (0,5), (8,0), (5,8), (1,5);
+CREATE TABLE it1 (
+int_nokey int(11) NOT NULL,
+int_key int(11) NOT NULL,
+KEY int_key (int_key)
+);
+INSERT INTO it1 VALUES
+(9,5), (0,4);
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+int_key
+0
+0
+2
+0
+3
+0
+7
+0
+7
+7
+9
+2
+9
+5
+0
+8
+5
+EXPLAIN
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY it1 index NULL int_key 4 NULL 2 Using index; Start temporary
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary
+DROP TABLE ot1, it1, it2;
+# End of BUG#38075
+#
+# BUG#31480: Incorrect result for nested subquery when executed via semi join
+#
+create table t1 (a int not null, b int not null);
+create table t2 (c int not null, d int not null);
+create table t3 (e int not null);
+insert into t1 values (1,10);
+insert into t1 values (2,10);
+insert into t1 values (1,20);
+insert into t1 values (2,20);
+insert into t1 values (3,20);
+insert into t1 values (2,30);
+insert into t1 values (4,40);
+insert into t2 values (2,10);
+insert into t2 values (2,20);
+insert into t2 values (4,10);
+insert into t2 values (5,10);
+insert into t2 values (3,20);
+insert into t2 values (2,40);
+insert into t3 values (10);
+insert into t3 values (30);
+insert into t3 values (10);
+insert into t3 values (20);
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select 1 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>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select 1 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
+2
+2
+3
+2
+drop table t1, t2, t3;
+#
+# Bug#48213 Materialized subselect crashes if using GEOMETRY type
+#
+CREATE TABLE t1 (
+pk int,
+a varchar(1),
+b varchar(4),
+c tinyblob,
+d blob,
+e mediumblob,
+f longblob,
+g tinytext,
+h text,
+i mediumtext,
+j longtext,
+k geometry,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff', 'ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))'));
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))'));
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY subselect2 eq_ref unique_key unique_key 13 func 1 1.00
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using MRR
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
+pk
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+pk
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+pk
+1
+2
+DROP TABLE t1, t2;
+# End of Bug#48213
+#
+# Bug#49198 Wrong result for second call of procedure
+# with view in subselect.
+#
+CREATE TABLE t1 (t1field integer, primary key (t1field));
+CREATE TABLE t2 (t2field integer, primary key (t2field));
+CREATE TABLE t3 (t3field integer, primary key (t3field));
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t1 VALUES(1),(2);
+INSERT INTO t2 VALUES(1),(2);
+INSERT INTO t3 VALUES(1),(2);
+PREPARE stmt FROM
+"
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2);
+";
+EXECUTE stmt;
+t1field
+1
+2
+EXECUTE stmt;
+t1field
+1
+2
+PREPARE stmt FROM
+"
+EXPLAIN
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2)
+ AND t1field IN (SELECT * FROM v3)
+";
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+DROP TABLE t1, t2, t3;
+DROP VIEW v2, v3;
+# End of Bug#49198
+#
+# Bug#45174: Incorrectly applied equality propagation caused wrong
+# result on a query with a materialized semi-join.
+#
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`varchar_key` varchar(1) NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `varchar_key` (`varchar_key`)
+);
+INSERT INTO `t1` VALUES (11,'m','m'),(12,'j','j'),(13,'z','z'),(14,'a','a'),(15,'',''),(16,'e','e'),(17,'t','t'),(19,'b','b'),(20,'w','w'),(21,'m','m'),(23,'',''),(24,'w','w'),(26,'e','e'),(27,'e','e'),(28,'p','p');
+CREATE TABLE `t2` (
+`varchar_nokey` varchar(1) NOT NULL
+);
+INSERT INTO `t2` VALUES ('v'),('u'),('n'),('l'),('h'),('u'),('n'),('j'),('k'),('e'),('i'),('u'),('n'),('b'),('x'),(''),('q'),('u');
+EXPLAIN EXTENDED SELECT varchar_nokey
+FROM t2
+WHERE ( `varchar_nokey` , `varchar_nokey` ) IN (
+SELECT `varchar_key` , `varchar_nokey`
+FROM t1
+WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
+1 PRIMARY subselect2 eq_ref unique_key unique_key 8 func 1 1.00
+2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
+SELECT varchar_nokey
+FROM t2
+WHERE ( `varchar_nokey` , `varchar_nokey` ) IN (
+SELECT `varchar_key` , `varchar_nokey`
+FROM t1
+WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
+varchar_nokey
+DROP TABLE t1, t2;
+# End of the test for bug#45174.
+#
+# BUG#43768: Prepared query with nested subqueries core dumps on second execution
+#
+create table t1 (
+id int(11) unsigned not null primary key auto_increment,
+partner_id varchar(35) not null,
+t1_status_id int(10) unsigned
+);
+insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"),
+("3", "partner3", "10"), ("4", "partner4", "10");
+create table t2 (
+id int(11) unsigned not null default '0',
+t1_line_id int(11) unsigned not null default '0',
+article_id varchar(20),
+sequence int(11) not null default '0',
+primary key (id,t1_line_id)
+);
+insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
+("2", "2", "sup", "2"), ("2", "3", "sup", "3"),
+("2", "4", "imp", "4"), ("3", "1", "sup", "0"),
+("4", "1", "sup", "0");
+create table t3 (
+id int(11) not null default '0',
+preceeding_id int(11) not null default '0',
+primary key (id,preceeding_id)
+);
+create table t4 (
+user_id varchar(50) not null,
+article_id varchar(20) not null,
+primary key (user_id,article_id)
+);
+insert into t4 values("nicke", "imp");
+prepare stmt from
+'select t1.partner_id
+from t1
+where
+ t1.id in (
+ select pl_inner.id
+ from t2 as pl_inner
+ where pl_inner.article_id in (
+ select t4.article_id from t4
+ where t4.user_id = \'nicke\'
+ )
+ )';
+execute stmt;
+partner_id
+partner2
+execute stmt;
+partner_id
+partner2
+drop table t1,t2,t3,t4;
+#
+# Bug#48623 Multiple subqueries are optimized incorrectly
+#
+CREATE TABLE t1(val VARCHAR(10));
+CREATE TABLE t2(val VARCHAR(10));
+CREATE TABLE t3(val VARCHAR(10));
+INSERT INTO t1 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t2 VALUES('aaa'), ('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t3 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+EXPLAIN
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+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
+1 PRIMARY subselect3 eq_ref unique_key unique_key 14 func 1
+1 PRIMARY subselect2 eq_ref unique_key unique_key 14 func 1
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+AND t1.val IN (SELECT t3.val FROM t3
+WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+val
+aaa
+eee
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+# End of Bug#48623
+#
+# LPBUG#602574: RQG: sql_select.cc:5385: bool greedy_search(JOIN*, table_map, uint,
+# uint): Assertion `join->best_read <
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+CREATE TABLE t2 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+CREATE TABLE t3 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+(NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+WHERE (varchar_key,varchar_key)
+IN (SELECT t1.varchar_key, t2 .varchar_key
+FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+)
+);
+varchar_key
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
new file mode 100644
index 00000000000..9a7b6748d29
--- /dev/null
+++ b/mysql-test/r/subselect_sj2.result
@@ -0,0 +1,726 @@
+drop table if exists t0, t1, t2, t3;
+drop view if exists v1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+a int,
+b int
+);
+insert into t1 values (1,1),(1,1),(2,2);
+create table t2 (
+a int,
+b int,
+key(b)
+);
+insert into t2 select a, a/2 from t0;
+select * from t1;
+a b
+1 1
+1 1
+2 2
+select * from t2;
+a b
+0 0
+1 1
+2 1
+3 2
+4 2
+5 3
+6 3
+7 4
+8 4
+9 5
+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 subselect2 ALL unique_key NULL NULL NULL 3
+1 PRIMARY t2 ref b b 5 test.t1.a 2
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+select * from t2 where b in (select a from t1);
+a b
+1 1
+2 1
+3 2
+4 2
+create table t3 (
+a int,
+b int,
+key(b),
+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;
+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 subselect2 eq_ref unique_key unique_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
+2 2 2 2 2
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+drop table t3;
+create table t3 (
+a int,
+b int,
+key(b),
+pk1 char(200), pk2 char(200),
+primary key(pk1, pk2)
+) engine=innodb;
+insert into t3 select
+A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
+from t0 A, t0 B where B.a <5;
+explain select * from t3 where b in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref b b 5 test.t0.a 1
+2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
+set @save_ecp= @@engine_condition_pushdown;
+set engine_condition_pushdown=0;
+select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);
+a b pk1 pk2
+0 0 0 0
+1 1 1 1
+2 2 2 2
+3 3 3 3
+4 4 4 4
+5 5 5 5
+6 6 6 6
+7 7 7 7
+8 8 8 8
+9 9 9 9
+10 10 10 10
+11 11 11 11
+12 12 12 12
+13 13 13 13
+set engine_condition_pushdown=@save_ecp;
+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 subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t2 index b b 5 NULL 10 Using index
+select * from t1;
+a b
+1 1
+1 1
+2 2
+select * from t1 where a in (select b from t2);
+a b
+1 1
+1 1
+2 2
+drop table t1, t2, t3;
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+create table t1 (a int, filler1 binary(200), filler2 binary(200));
+insert into t1 select a, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+10, 'filler123456', 'filler123456' from t0;
+create table t2 as select * from t1;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+insert into t1 values (2, 'duplicate ok', 'duplicate ok');
+insert into t1 values (18, 'duplicate ok', 'duplicate ok');
+insert into t2 values (3, 'duplicate ok', 'duplicate ok');
+insert into t2 values (19, 'duplicate ok', 'duplicate ok');
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY it ALL NULL NULL NULL NULL 22
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+a mid(filler1, 1,10) Z
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+2 duplicate 1
+18 duplicate 1
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot ALL NULL NULL NULL NULL 22
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY it ALL NULL NULL NULL NULL 32
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+a mid(filler1, 1,10) length(filler1)=length(filler2)
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+3 duplicate 1
+19 duplicate 1
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY it ALL NULL NULL NULL NULL 22
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+a mid(filler1, 1,10) Z
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+2 duplicate 1
+18 duplicate 1
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot ALL NULL NULL NULL NULL 22
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY it ALL NULL NULL NULL NULL 52
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+a mid(filler1, 1,10) length(filler1)=length(filler2)
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+3 duplicate 1
+19 duplicate 1
+drop table t1, t2;
+create table t1 (a int, b int, key(a));
+create table t2 (a int, b int, key(a));
+create table t3 (a int, b int, key(a));
+insert into t1 select a,a from t0;
+insert into t2 select a,a from t0;
+insert into t3 select a,a from t0;
+t2 and t3 must be use 'ref', not 'ALL':
+explain select *
+from t0 where a in
+(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
+1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
+1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
+drop table t0, t1,t2,t3;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name),
+INDEX (Population)
+);
+CREATE TABLE t3 (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+EXPLAIN
+SELECT Name FROM t2
+WHERE t2.Code IN (SELECT Country FROM t1 WHERE Population > 5000000)
+AND
+t2.Code IN (SELECT Country FROM t3
+WHERE Language='English' AND Percentage > 10 AND
+t2.Population > 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Using MRR
+1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where
+1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t3.Country 1 Using index condition; Using where
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+Code char(3) NOT NULL DEFAULT '',
+Name char(52) NOT NULL DEFAULT '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
+Region char(26) NOT NULL DEFAULT '',
+SurfaceArea float(10,2) NOT NULL DEFAULT '0.00',
+IndepYear smallint(6) DEFAULT NULL,
+Population int(11) NOT NULL DEFAULT '0',
+LifeExpectancy float(3,1) DEFAULT NULL,
+GNP float(10,2) DEFAULT NULL,
+GNPOld float(10,2) DEFAULT NULL,
+LocalName char(45) NOT NULL DEFAULT '',
+GovernmentForm char(45) NOT NULL DEFAULT '',
+HeadOfState char(60) DEFAULT NULL,
+Capital int(11) DEFAULT NULL,
+Code2 char(2) NOT NULL DEFAULT '',
+PRIMARY KEY (Code)
+);
+CREATE TABLE t2 (
+ID int(11) NOT NULL AUTO_INCREMENT,
+Name char(35) NOT NULL DEFAULT '',
+CountryCode char(3) NOT NULL DEFAULT '',
+District char(20) NOT NULL DEFAULT '',
+Population int(11) NOT NULL DEFAULT '0',
+PRIMARY KEY (ID),
+KEY CountryCode (CountryCode)
+);
+Fill the table with test data
+This must not use LooseScan:
+EXPLAIN SELECT Name FROM t1
+WHERE t1.Code IN (
+SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
+SELECT Name FROM t1
+WHERE t1.Code IN (
+SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+Name
+Austria
+Canada
+China
+Czech Republic
+drop table t1, t2;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(c INT);
+CREATE PROCEDURE p1(v1 int)
+BEGIN
+SELECT 1 FROM t1 WHERE a = v1 AND a IN (SELECT c FROM t2);
+END
+//
+CREATE PROCEDURE p2(v1 int)
+BEGIN
+SELECT 1 FROM t1 WHERE a IN (SELECT c FROM t2);
+END
+//
+CREATE PROCEDURE p3(v1 int)
+BEGIN
+SELECT 1
+FROM
+t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+t1 t57,t1 t58,t1 t59,t1 t60
+WHERE t01.a IN (SELECT c FROM t2);
+END
+//
+CREATE PROCEDURE p4(v1 int)
+BEGIN
+SELECT 1
+FROM
+t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+t1 t57,t1 t58,t1 t59,t1 t60
+WHERE t01.a = v1 AND t01.a IN (SELECT c FROM t2);
+END
+//
+CALL p1(1);
+1
+CALL p2(1);
+1
+CALL p3(1);
+1
+CALL p4(1);
+1
+DROP TABLE t1, t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+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;
+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
+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
+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
+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`))
+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
+(select t1.a from t1, t2 where t2.a=t0.a and t1.b=t2.b);
+a
+0
+1
+2
+3
+drop table t0, t1, t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL,
+PRIMARY KEY (id));
+CREATE TABLE t2 (
+id int(11) NOT NULL,
+fid int(11) NOT NULL,
+PRIMARY KEY (id));
+insert into t1 values(1);
+insert into t2 values(1,7503),(2,1);
+explain select count(*)
+from t1
+where fid IN (select fid from t2 where (id between 7502 and 8420) order by fid );
+ERROR 42S22: Unknown column 'fid' in 'IN/ALL/ANY subquery'
+drop table t1, t2;
+create table t1 (a int, b int, key (a), key (b));
+insert into t1 values (2,4),(2,4),(2,4);
+select t1.a from t1
+where
+t1.a in (select 1 from t1 where t1.a in (select 1 from t1) group by t1.a);
+a
+drop table t1;
+create table t1(a int,b int,key(a),key(b));
+insert into t1 values (1,1),(2,2),(3,3);
+select 1 from t1
+where t1.a not in (select 1 from t1
+where t1.a in (select 1 from t1)
+group by t1.b);
+1
+1
+1
+drop table t1;
+CREATE TABLE t1
+(EMPNUM CHAR(3) NOT NULL,
+EMPNAME CHAR(20),
+GRADE DECIMAL(4),
+CITY CHAR(15));
+CREATE TABLE t2
+(PNUM CHAR(3) NOT NULL,
+PNAME CHAR(20),
+PTYPE CHAR(6),
+BUDGET DECIMAL(9),
+CITY CHAR(15));
+CREATE TABLE t3
+(EMPNUM CHAR(3) NOT NULL,
+PNUM CHAR(3) NOT NULL,
+HOURS DECIMAL(5));
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+SELECT * FROM t1;
+EMPNUM EMPNAME GRADE CITY
+E1 Alice 12 Deale
+E2 Betty 10 Vienna
+E3 Carmen 13 Vienna
+E4 Don 12 Deale
+E5 Ed 13 Akron
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP INDEX t1_IDX ON t1;
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (f1 INT NOT NULL);
+CREATE VIEW v1 (a) AS SELECT f1 IN (SELECT f1 FROM t1) FROM t1;
+SELECT * FROM v1;
+a
+drop view v1;
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+create table t3 (pk int, a int, primary key(pk));
+insert into t3 select a,a from t0;
+explain
+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
+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);
+create table t2 (a char(200), b char(200), c char(200), primary key (a,b,c)) engine=innodb;
+insert into t2 select concat(a, repeat('X',198)),repeat('B',200),repeat('B',200) from t1;
+insert into t2 select concat(a, repeat('Y',198)),repeat('B',200),repeat('B',200) from t1;
+alter table t2 add filler1 int;
+insert into t1 select A.a + 10*(B.a + 10*C.a) from t1 A, t1 B, t1 C;
+set @save_join_buffer_size=@@join_buffer_size;
+set join_buffer_size=1;
+select * from t2 where filler1 in ( select a from t1);
+a b c filler1
+set join_buffer_size=default;
+drop table t1, t2;
+create table t1 (a int not null);
+drop procedure if exists p1;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLEXCEPTION select a from t1;
+prepare s1 from '
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in ( select a from t1)
+ )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
+execute s1;
+END;
+|
+call p1();
+a
+drop procedure p1;
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int) as select A.a + 10 *(B.a + 10*C.a) as a from t0 A, t0 B, t0 C;
+create table t2 (id int, a int, primary key(id), key(a)) as select a as id, a as a from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL DEFAULT '0',
+ `a` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `a` (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+set @a=0;
+create table t3 as select * from t2 limit 0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+alter table t3 add primary key(id), add key(a);
+The following must use loose index scan over t3, key a:
+explain select count(a) from t2 where a in ( SELECT a FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index a a 5 NULL 1000 Using index
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t3 index a a 5 NULL 30000 Using index
+select count(a) from t2 where a in ( SELECT a FROM t3);
+count(a)
+1000
+drop table t0,t1,t2,t3;
+
+BUG#42740: crash in optimize_semijoin_nests
+
+create table t1 (c6 timestamp,key (c6)) engine=innodb;
+create table t2 (c2 double) engine=innodb;
+explain select 1 from t2 where c2 = any (select log10(null) from t1 where c6 <null) ;
+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
+drop table t1, t2;
+#
+# BUG#42742: crash in setup_sj_materialization, Copy_field::set
+#
+create table t3 ( c1 year) engine=innodb;
+insert into t3 values (2135),(2142);
+create table t2 (c1 tinytext,c2 text,c6 timestamp) engine=innodb;
+# The following must not crash, EXPLAIN should show one SJ strategy, not a mix:
+explain select 1 from t2 where
+c2 in (select 1 from t3, t2) and
+c1 in (select convert(c6,char(1)) from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2)
+drop table t2, t3;
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
new file mode 100644
index 00000000000..ab97d59302c
--- /dev/null
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -0,0 +1,740 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+drop table if exists t0, t1, t2, t3;
+drop view if exists v1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+a int,
+b int
+);
+insert into t1 values (1,1),(1,1),(2,2);
+create table t2 (
+a int,
+b int,
+key(b)
+);
+insert into t2 select a, a/2 from t0;
+select * from t1;
+a b
+1 1
+1 1
+2 2
+select * from t2;
+a b
+0 0
+1 1
+2 1
+3 2
+4 2
+5 3
+6 3
+7 4
+8 4
+9 5
+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 subselect2 ALL unique_key NULL NULL NULL 3
+1 PRIMARY t2 ref b b 5 test.t1.a 2 Using join buffer (flat, BKA join)
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+select * from t2 where b in (select a from t1);
+a b
+1 1
+2 1
+3 2
+4 2
+create table t3 (
+a int,
+b int,
+key(b),
+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;
+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 subselect2 eq_ref unique_key unique_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
+2 2 2 2 2
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+drop table t3;
+create table t3 (
+a int,
+b int,
+key(b),
+pk1 char(200), pk2 char(200),
+primary key(pk1, pk2)
+) engine=innodb;
+insert into t3 select
+A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
+from t0 A, t0 B where B.a <5;
+explain select * from t3 where b in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY t3 ref b b 5 test.t0.a 1 Using join buffer (flat, BKA join)
+2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
+set @save_ecp= @@engine_condition_pushdown;
+set engine_condition_pushdown=0;
+select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);
+a b pk1 pk2
+0 0 0 0
+1 1 1 1
+2 2 2 2
+3 3 3 3
+4 4 4 4
+5 5 5 5
+6 6 6 6
+7 7 7 7
+8 8 8 8
+9 9 9 9
+10 10 10 10
+11 11 11 11
+12 12 12 12
+13 13 13 13
+set engine_condition_pushdown=@save_ecp;
+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 subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t2 index b b 5 NULL 10 Using index
+select * from t1;
+a b
+1 1
+1 1
+2 2
+select * from t1 where a in (select b from t2);
+a b
+1 1
+1 1
+2 2
+drop table t1, t2, t3;
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+create table t1 (a int, filler1 binary(200), filler2 binary(200));
+insert into t1 select a, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+10, 'filler123456', 'filler123456' from t0;
+create table t2 as select * from t1;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+insert into t1 values (2, 'duplicate ok', 'duplicate ok');
+insert into t1 values (18, 'duplicate ok', 'duplicate ok');
+insert into t2 values (3, 'duplicate ok', 'duplicate ok');
+insert into t2 values (19, 'duplicate ok', 'duplicate ok');
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY it ALL NULL NULL NULL NULL 22
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+a mid(filler1, 1,10) Z
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+2 duplicate 1
+18 duplicate 1
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot ALL NULL NULL NULL NULL 22
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY it ALL NULL NULL NULL NULL 32
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+a mid(filler1, 1,10) length(filler1)=length(filler2)
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+3 duplicate 1
+19 duplicate 1
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY it ALL NULL NULL NULL NULL 22
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+a mid(filler1, 1,10) Z
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+2 duplicate 1
+18 duplicate 1
+explain select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot ALL NULL NULL NULL NULL 22
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY it ALL NULL NULL NULL NULL 52
+select
+a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+a mid(filler1, 1,10) length(filler1)=length(filler2)
+0 filler1234 1
+1 filler1234 1
+2 filler1234 1
+3 filler1234 1
+4 filler1234 1
+5 filler1234 1
+6 filler1234 1
+7 filler1234 1
+8 filler1234 1
+9 filler1234 1
+10 filler1234 1
+11 filler1234 1
+12 filler1234 1
+13 filler1234 1
+14 filler1234 1
+15 filler1234 1
+16 filler1234 1
+17 filler1234 1
+18 filler1234 1
+19 filler1234 1
+3 duplicate 1
+19 duplicate 1
+drop table t1, t2;
+create table t1 (a int, b int, key(a));
+create table t2 (a int, b int, key(a));
+create table t3 (a int, b int, key(a));
+insert into t1 select a,a from t0;
+insert into t2 select a,a from t0;
+insert into t3 select a,a from t0;
+t2 and t3 must be use 'ref', not 'ALL':
+explain select *
+from t0 where a in
+(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
+1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
+1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
+drop table t0, t1,t2,t3;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name),
+INDEX (Population)
+);
+CREATE TABLE t3 (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+EXPLAIN
+SELECT Name FROM t2
+WHERE t2.Code IN (SELECT Country FROM t1 WHERE Population > 5000000)
+AND
+t2.Code IN (SELECT Country FROM t3
+WHERE Language='English' AND Percentage > 10 AND
+t2.Population > 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Using MRR
+1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (flat, BKA join)
+1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t3.Country 1 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join)
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+Code char(3) NOT NULL DEFAULT '',
+Name char(52) NOT NULL DEFAULT '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
+Region char(26) NOT NULL DEFAULT '',
+SurfaceArea float(10,2) NOT NULL DEFAULT '0.00',
+IndepYear smallint(6) DEFAULT NULL,
+Population int(11) NOT NULL DEFAULT '0',
+LifeExpectancy float(3,1) DEFAULT NULL,
+GNP float(10,2) DEFAULT NULL,
+GNPOld float(10,2) DEFAULT NULL,
+LocalName char(45) NOT NULL DEFAULT '',
+GovernmentForm char(45) NOT NULL DEFAULT '',
+HeadOfState char(60) DEFAULT NULL,
+Capital int(11) DEFAULT NULL,
+Code2 char(2) NOT NULL DEFAULT '',
+PRIMARY KEY (Code)
+);
+CREATE TABLE t2 (
+ID int(11) NOT NULL AUTO_INCREMENT,
+Name char(35) NOT NULL DEFAULT '',
+CountryCode char(3) NOT NULL DEFAULT '',
+District char(20) NOT NULL DEFAULT '',
+Population int(11) NOT NULL DEFAULT '0',
+PRIMARY KEY (ID),
+KEY CountryCode (CountryCode)
+);
+Fill the table with test data
+This must not use LooseScan:
+EXPLAIN SELECT Name FROM t1
+WHERE t1.Code IN (
+SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
+1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
+SELECT Name FROM t1
+WHERE t1.Code IN (
+SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+Name
+Austria
+Canada
+China
+Czech Republic
+drop table t1, t2;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(c INT);
+CREATE PROCEDURE p1(v1 int)
+BEGIN
+SELECT 1 FROM t1 WHERE a = v1 AND a IN (SELECT c FROM t2);
+END
+//
+CREATE PROCEDURE p2(v1 int)
+BEGIN
+SELECT 1 FROM t1 WHERE a IN (SELECT c FROM t2);
+END
+//
+CREATE PROCEDURE p3(v1 int)
+BEGIN
+SELECT 1
+FROM
+t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+t1 t57,t1 t58,t1 t59,t1 t60
+WHERE t01.a IN (SELECT c FROM t2);
+END
+//
+CREATE PROCEDURE p4(v1 int)
+BEGIN
+SELECT 1
+FROM
+t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+t1 t57,t1 t58,t1 t59,t1 t60
+WHERE t01.a = v1 AND t01.a IN (SELECT c FROM t2);
+END
+//
+CALL p1(1);
+1
+CALL p2(1);
+1
+CALL p3(1);
+1
+CALL p4(1);
+1
+DROP TABLE t1, t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+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;
+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
+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)
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using where; End temporary; Using join buffer (incremental, BKA join)
+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`))
+update t1 set a=3, b=11 where a=4;
+update t2 set b=11 where a=3;
+# Not anymore:
+# The following query gives wrong result due to Bug#49129
+select * from t0 where t0.a in
+(select t1.a from t1, t2 where t2.a=t0.a and t1.b=t2.b);
+a
+0
+1
+2
+3
+drop table t0, t1, t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL,
+PRIMARY KEY (id));
+CREATE TABLE t2 (
+id int(11) NOT NULL,
+fid int(11) NOT NULL,
+PRIMARY KEY (id));
+insert into t1 values(1);
+insert into t2 values(1,7503),(2,1);
+explain select count(*)
+from t1
+where fid IN (select fid from t2 where (id between 7502 and 8420) order by fid );
+ERROR 42S22: Unknown column 'fid' in 'IN/ALL/ANY subquery'
+drop table t1, t2;
+create table t1 (a int, b int, key (a), key (b));
+insert into t1 values (2,4),(2,4),(2,4);
+select t1.a from t1
+where
+t1.a in (select 1 from t1 where t1.a in (select 1 from t1) group by t1.a);
+a
+drop table t1;
+create table t1(a int,b int,key(a),key(b));
+insert into t1 values (1,1),(2,2),(3,3);
+select 1 from t1
+where t1.a not in (select 1 from t1
+where t1.a in (select 1 from t1)
+group by t1.b);
+1
+1
+1
+drop table t1;
+CREATE TABLE t1
+(EMPNUM CHAR(3) NOT NULL,
+EMPNAME CHAR(20),
+GRADE DECIMAL(4),
+CITY CHAR(15));
+CREATE TABLE t2
+(PNUM CHAR(3) NOT NULL,
+PNAME CHAR(20),
+PTYPE CHAR(6),
+BUDGET DECIMAL(9),
+CITY CHAR(15));
+CREATE TABLE t3
+(EMPNUM CHAR(3) NOT NULL,
+PNUM CHAR(3) NOT NULL,
+HOURS DECIMAL(5));
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+SELECT * FROM t1;
+EMPNUM EMPNAME GRADE CITY
+E1 Alice 12 Deale
+E2 Betty 10 Vienna
+E3 Carmen 13 Vienna
+E4 Don 12 Deale
+E5 Ed 13 Akron
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP INDEX t1_IDX ON t1;
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (f1 INT NOT NULL);
+CREATE VIEW v1 (a) AS SELECT f1 IN (SELECT f1 FROM t1) FROM t1;
+SELECT * FROM v1;
+a
+drop view v1;
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+create table t3 (pk int, a int, primary key(pk));
+insert into t3 select a,a from t0;
+explain
+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; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 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);
+create table t2 (a char(200), b char(200), c char(200), primary key (a,b,c)) engine=innodb;
+insert into t2 select concat(a, repeat('X',198)),repeat('B',200),repeat('B',200) from t1;
+insert into t2 select concat(a, repeat('Y',198)),repeat('B',200),repeat('B',200) from t1;
+alter table t2 add filler1 int;
+insert into t1 select A.a + 10*(B.a + 10*C.a) from t1 A, t1 B, t1 C;
+set @save_join_buffer_size=@@join_buffer_size;
+set join_buffer_size=1;
+select * from t2 where filler1 in ( select a from t1);
+a b c filler1
+set join_buffer_size=default;
+drop table t1, t2;
+create table t1 (a int not null);
+drop procedure if exists p1;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLEXCEPTION select a from t1;
+prepare s1 from '
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in ( select a from t1)
+ )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
+execute s1;
+END;
+|
+call p1();
+a
+drop procedure p1;
+drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int) as select A.a + 10 *(B.a + 10*C.a) as a from t0 A, t0 B, t0 C;
+create table t2 (id int, a int, primary key(id), key(a)) as select a as id, a as a from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL DEFAULT '0',
+ `a` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `a` (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+set @a=0;
+create table t3 as select * from t2 limit 0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+alter table t3 add primary key(id), add key(a);
+The following must use loose index scan over t3, key a:
+explain select count(a) from t2 where a in ( SELECT a FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index a a 5 NULL 1000 Using index
+1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+2 SUBQUERY t3 index a a 5 NULL 30000 Using index
+select count(a) from t2 where a in ( SELECT a FROM t3);
+count(a)
+1000
+drop table t0,t1,t2,t3;
+
+BUG#42740: crash in optimize_semijoin_nests
+
+create table t1 (c6 timestamp,key (c6)) engine=innodb;
+create table t2 (c2 double) engine=innodb;
+explain select 1 from t2 where c2 = any (select log10(null) from t1 where c6 <null) ;
+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
+drop table t1, t2;
+#
+# BUG#42742: crash in setup_sj_materialization, Copy_field::set
+#
+create table t3 ( c1 year) engine=innodb;
+insert into t3 values (2135),(2142);
+create table t2 (c1 tinytext,c2 text,c6 timestamp) engine=innodb;
+# The following must not crash, EXPLAIN should show one SJ strategy, not a mix:
+explain select 1 from t2 where
+c2 in (select 1 from t3, t2) and
+c1 in (select convert(c6,char(1)) from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2); Using join buffer (incremental, BNL join)
+drop table t2, t3;
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
new file mode 100644
index 00000000000..ee52f372f81
--- /dev/null
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -0,0 +1,1165 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
+set @save_optimizer_switch=@@optimizer_switch;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+create table t11(a int, b int);
+create table t10 (pk int, a int, primary key(pk));
+insert into t10 select a,a from t0;
+create table t12 like t10;
+insert into t12 select * from t10;
+Flattened because of dependency, t10=func(t1)
+explain select * from t1 where a in (select pk from t10);
+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 t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+select * from t1 where a in (select pk from t10);
+a b
+0 0
+1 1
+2 2
+A confluent case of dependency
+explain select * from t1 where a in (select a from t10 where pk=12);
+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
+select * from t1 where a in (select a from t10 where pk=12);
+a b
+explain select * from t1 where a in (select a from t10 where pk=9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t10 const PRIMARY PRIMARY 4 const 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+select * from t1 where a in (select a from t10 where pk=9);
+a b
+An empty table inside
+explain select * from t1 where a in (select a from t11);
+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
+select * from t1 where a in (select a from t11);
+a b
+explain select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+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 t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using index
+select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+a b
+0 0
+1 1
+2 2
+flattening a nested subquery
+explain select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+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 t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKA join)
+1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 Using index
+select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+a b
+0 0
+1 1
+2 2
+flattening subquery w/ several tables
+explain extended select * from t1 where a in (select t10.pk from t10, t12 where t12.pk=t10.a);
+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
+1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using where; Using join buffer (flat, BKA join)
+1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t10`.`pk` = `test`.`t1`.`a`) and (`test`.`t12`.`pk` = `test`.`t10`.`a`))
+subqueries within outer joins go into ON expr.
+explAin extended
+select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
+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
+1 PRIMARY A ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join)
+1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (incrementAl, BNL join)
+2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on((<in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))) And (`test`.`A`.`A` = `test`.`t1`.`A`))) where 1
+t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
+explAin extended
+select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
+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
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join)
+2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on((<in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))) And (`test`.`t2`.`A` = `test`.`t1`.`A`))) where 1
+we shouldn't flatten if we're going to get a join of > MAX_TABLES.
+explain select * from
+t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
+t1 s10, t1 s11, t1 s12, t1 s13, t1 s14,t1 s15,t1 s16,t1 s17,t1 s18,t1 s19,
+t1 s20, t1 s21, t1 s22, t1 s23, t1 s24,t1 s25,t1 s26,t1 s27,t1 s28,t1 s29,
+t1 s30, t1 s31, t1 s32, t1 s33, t1 s34,t1 s35,t1 s36,t1 s37,t1 s38,t1 s39,
+t1 s40, t1 s41, t1 s42, t1 s43, t1 s44,t1 s45,t1 s46,t1 s47,t1 s48,t1 s49
+where
+s00.a in (
+select m00.a from
+t1 m00, t1 m01, t1 m02, t1 m03, t1 m04,t1 m05,t1 m06,t1 m07,t1 m08,t1 m09,
+t1 m10, t1 m11, t1 m12, t1 m13, t1 m14,t1 m15,t1 m16,t1 m17,t1 m18,t1 m19
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY s00 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY s01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY s02 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s03 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s04 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s05 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s06 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s07 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s08 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s09 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s10 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s11 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s12 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s13 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s14 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s15 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s16 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s17 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s18 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s19 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s20 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s21 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s22 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s23 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s24 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s25 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s26 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s27 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s28 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s29 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s30 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s31 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s32 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s33 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s34 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s35 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s36 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s37 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s38 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s39 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s40 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s41 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s42 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s43 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s44 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s45 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s46 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m00 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
+select * from
+t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+where t1.a < 5;
+a b a b
+0 0 0 0
+1 1 1 1
+2 2 2 2
+prepare s1 from
+' select * from
+ t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+ where t1.a < 5';
+execute s1;
+a b a b
+0 0 0 0
+1 1 1 1
+2 2 2 2
+execute s1;
+a b a b
+0 0 0 0
+1 1 1 1
+2 2 2 2
+insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B;
+explain extended select * from t1 where a in (select pk from t10 where pk<3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3))
+drop table t0, t1, t2;
+drop table t10, t11, t12;
+
+Bug#37899: Wrongly checked optimization prerequisite caused failed
+assertion.
+
+CREATE TABLE t1 (
+`pk` int(11),
+`varchar_nokey` varchar(5)
+);
+INSERT INTO t1 VALUES
+(1,'qk'),(2,'j'),(3,'aew');
+SELECT *
+FROM t1
+WHERE varchar_nokey IN (
+SELECT
+varchar_nokey
+FROM
+t1
+) XOR pk = 30;
+pk varchar_nokey
+1 qk
+2 j
+3 aew
+drop table t1;
+#
+# BUG#41842: Semi-join materialization strategy crashes when the upper query has HAVING
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+int_nokey int(11) NOT NULL,
+time_key time NOT NULL,
+datetime_key datetime NOT NULL,
+datetime_nokey datetime NOT NULL,
+varchar_key varchar(1) NOT NULL,
+varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY time_key (time_key),
+KEY datetime_key (datetime_key),
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t1 VALUES
+(1,0, '00:16:10','2008-09-03 14:25:40','2008-09-03 14:25:40','h','h'),
+(2,7, '00:00:00','2001-01-13 00:00:00','2001-01-13 00:00:00','',''),
+(3,0, '00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(4,2, '16:29:24','2000-10-16 01:39:08','2000-10-16 01:39:08','w','w'),
+(5,1, '09:23:32','0000-00-00 00:00:00','0000-00-00 00:00:00','p','p'),
+(6,3, '00:00:00','2007-12-02 00:00:00','2007-12-02 00:00:00','o','o'),
+(7,3, '00:00:00','2008-09-11 00:00:00','2008-09-11 00:00:00','',''),
+(8,0, '13:59:04','0000-00-00 00:00:00','0000-00-00 00:00:00','s','s'),
+(9,7, '09:01:06','0000-00-00 00:00:00','0000-00-00 00:00:00','d','d'),
+(10,5,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','n','n'),
+(11,0,'21:06:46','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(12,2,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','',''),
+(13,6,'14:45:34','2003-07-28 02:34:08','2003-07-28 02:34:08','w','w'),
+(14,1,'15:04:12','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(15,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(16,0,'15:55:23','2004-03-17 00:32:27','2004-03-17 00:32:27','p','p'),
+(17,1,'16:30:00','2004-12-27 19:20:00','2004-12-27 19:20:00','d','d'),
+(18,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','h','h'),
+(19,0,'14:13:26','2008-11-09 05:53:48','2008-11-09 05:53:48','o','o'),
+(20,0,'00:00:00','2009-10-11 06:58:04','2009-10-11 06:58:04','k','k');
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+int_nokey int(11) NOT NULL,
+time_key time NOT NULL,
+datetime_key datetime NOT NULL,
+datetime_nokey datetime NOT NULL,
+varchar_key varchar(1) NOT NULL,
+varchar_nokey varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY time_key (time_key),
+KEY datetime_key (datetime_key),
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(10,0,'19:39:13','0000-00-00 00:00:00','0000-00-00 00:00:00','g','g'),
+(11,8,'03:43:53','0000-00-00 00:00:00','0000-00-00 00:00:00','b','b');
+SELECT OUTR.datetime_nokey AS X FROM t1 AS OUTR
+WHERE
+OUTR.varchar_nokey IN (SELECT
+INNR . varchar_nokey AS Y
+FROM t2 AS INNR
+WHERE
+INNR . datetime_key >= INNR . time_key OR
+INNR . pk = INNR . int_nokey
+)
+AND OUTR . varchar_nokey <= 'w'
+HAVING X > '2012-12-12';
+X
+drop table t1, t2;
+#
+# Bug#45191: Incorrectly initialized semi-join led to a wrong result.
+#
+CREATE TABLE STAFF (EMPNUM CHAR(3) NOT NULL,
+EMPNAME CHAR(20), GRADE DECIMAL(4), CITY CHAR(15));
+CREATE TABLE PROJ (PNUM CHAR(3) NOT NULL,
+PNAME CHAR(20), PTYPE CHAR(6),
+BUDGET DECIMAL(9),
+CITY CHAR(15));
+CREATE TABLE WORKS (EMPNUM CHAR(3) NOT NULL,
+PNUM CHAR(3) NOT NULL, HOURS DECIMAL(5));
+INSERT INTO STAFF VALUES ('E1','Alice',12,'Deale');
+INSERT INTO STAFF VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO STAFF VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO STAFF VALUES ('E4','Don',12,'Deale');
+INSERT INTO STAFF VALUES ('E5','Ed',13,'Akron');
+INSERT INTO PROJ VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO PROJ VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO PROJ VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO PROJ VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO PROJ VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO PROJ VALUES ('P6','PAYR','Design',50000,'Deale');
+INSERT INTO WORKS VALUES ('E1','P1',40);
+INSERT INTO WORKS VALUES ('E1','P2',20);
+INSERT INTO WORKS VALUES ('E1','P3',80);
+INSERT INTO WORKS VALUES ('E1','P4',20);
+INSERT INTO WORKS VALUES ('E1','P5',12);
+INSERT INTO WORKS VALUES ('E1','P6',12);
+INSERT INTO WORKS VALUES ('E2','P1',40);
+INSERT INTO WORKS VALUES ('E2','P2',80);
+INSERT INTO WORKS VALUES ('E3','P2',20);
+INSERT INTO WORKS VALUES ('E4','P2',20);
+INSERT INTO WORKS VALUES ('E4','P4',40);
+INSERT INTO WORKS VALUES ('E4','P5',80);
+set optimizer_switch=@save_optimizer_switch;
+set optimizer_switch='materialization=off';
+explain SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+(SELECT EMPNUM FROM WORKS
+WHERE PNUM IN
+(SELECT PNUM FROM PROJ));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY STAFF ALL NULL NULL NULL NULL 5
+1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; FirstMatch(STAFF); Using join buffer (incremental, BNL join)
+SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+(SELECT EMPNUM FROM WORKS
+WHERE PNUM IN
+(SELECT PNUM FROM PROJ));
+EMPNUM EMPNAME
+E1 Alice
+E2 Betty
+E3 Carmen
+E4 Don
+set optimizer_switch=@save_optimizer_switch;
+drop table STAFF,WORKS,PROJ;
+# End of bug#45191
+#
+# Bug#46550 Azalea returning duplicate results for some IN subqueries
+# w/ semijoin=on
+#
+DROP TABLE IF EXISTS t0, t1, t2;
+CREATE TABLE t0 (
+int_key int(11) DEFAULT NULL,
+varchar_key varchar(1) DEFAULT NULL,
+varchar_nokey varchar(1) DEFAULT NULL,
+KEY int_key (int_key),
+KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t0 VALUES
+(1,'m','m'),
+(40,'h','h'),
+(1,'r','r'),
+(1,'h','h'),
+(9,'x','x'),
+(NULL,'q','q'),
+(NULL,'k','k'),
+(7,'l','l'),
+(182,'k','k'),
+(202,'a','a'),
+(7,'x','x'),
+(6,'j','j'),
+(119,'z','z'),
+(4,'d','d'),
+(5,'h','h'),
+(1,'u','u'),
+(3,'q','q'),
+(7,'a','a'),
+(3,'e','e'),
+(6,'l','l');
+CREATE TABLE t1 (
+int_key int(11) DEFAULT NULL,
+varchar_key varchar(1) DEFAULT NULL,
+varchar_nokey varchar(1) DEFAULT NULL,
+KEY int_key (int_key),
+KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t1 VALUES (7,NULL,NULL),(4,'x','x');
+CREATE TABLE t2 (
+int_key int(11) DEFAULT NULL,
+varchar_key varchar(1) DEFAULT NULL,
+varchar_nokey varchar(1) DEFAULT NULL,
+KEY int_key (int_key),
+KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t2 VALUES (123,NULL,NULL);
+SELECT int_key
+FROM t0
+WHERE varchar_nokey IN (
+SELECT t1 .varchar_key from t1
+);
+int_key
+9
+7
+SELECT t0.int_key
+FROM t0
+WHERE t0.varchar_nokey IN (
+SELECT t1_1 .varchar_key
+FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+int_key
+9
+7
+SELECT t0.int_key
+FROM t0, t2
+WHERE t0.varchar_nokey IN (
+SELECT t1_1 .varchar_key
+FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+int_key
+9
+7
+DROP TABLE t0, t1, t2;
+# End of bug#46550
+#
+# Bug #46744 Crash in optimize_semijoin_nests on empty view
+# with limit and procedure.
+#
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE TABLE t1 ( f1 int );
+CREATE TABLE t2 ( f1 int );
+insert into t2 values (5), (7);
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
+create procedure p1()
+select COUNT(*)
+FROM v1 WHERE f1 IN
+(SELECT f1 FROM t2 WHERE f1 = ANY (SELECT f1 FROM v1));
+SET SESSION optimizer_switch = 'semijoin=on';
+CALL p1();
+COUNT(*)
+0
+SET SESSION optimizer_switch = 'semijoin=off';
+CALL p1();
+COUNT(*)
+0
+drop table t1, t2;
+drop view v1;
+drop procedure p1;
+set SESSION optimizer_switch=@save_optimizer_switch;
+# End of bug#46744
+
+Bug#46797 "Crash in fix_semijoin_strategies_for_picked_join_order
+with semijoin=on"
+
+CREATE TABLE t1 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+CREATE TABLE t2 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+CREATE TABLE t3 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+(NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+WHERE (varchar_key,varchar_key)
+IN (SELECT t1.varchar_key, t2 .varchar_key
+FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+)
+);
+varchar_key
+DROP TABLE t1, t2, t3;
+#
+# Bug#46556 Returning incorrect, empty results for some IN subqueries
+# w/semijoin=on
+#
+CREATE TABLE t0 (
+pk INTEGER,
+vkey VARCHAR(1),
+vnokey VARCHAR(1),
+PRIMARY KEY (pk),
+KEY vkey(vkey)
+);
+INSERT INTO t0
+VALUES (1,'g','g'), (2,'v','v'), (3,'t','t'), (4,'u','u'), (5,'n','n');
+EXPLAIN EXTENDED SELECT vkey FROM t0 WHERE pk IN
+(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t0 ALL PRIMARY NULL NULL NULL 5 100.00
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where; Using join buffer (flat, BKA join)
+1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`) and (`test`.`t1`.`pk` = `test`.`t0`.`pk`))
+SELECT vkey FROM t0 WHERE pk IN
+(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+vkey
+g
+v
+t
+u
+n
+DROP TABLE t0;
+# End of bug#46556
+
+Bug #48073 Subquery on char columns from view crashes Mysql
+
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+CREATE TABLE t1 (
+city VARCHAR(50) NOT NULL,
+country_id SMALLINT UNSIGNED NOT NULL
+);
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+CREATE TABLE t2 (
+country_id SMALLINT UNSIGNED NOT NULL,
+country VARCHAR(50) NOT NULL
+);
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'American Samoa') ;
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+SELECT country
+FROM t2
+WHERE LEFT(country, 1) = "A"
+);
+city country_id
+Algeria 2
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+SELECT country
+FROM v1
+);
+city country_id
+Algeria 2
+drop table t1, t2;
+drop view v1;
+# End of bug#48073
+
+Bug#48834: Procedure with view + subquery + semijoin=on
+crashes on second call.
+
+SET SESSION optimizer_switch ='semijoin=on';
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+CREATE VIEW v1 AS
+SELECT t1field as v1field
+FROM t1 A
+WHERE A.t1field IN (SELECT t1field FROM t2 );
+CREATE VIEW v2 AS
+SELECT t2field as v2field
+FROM t2 A
+WHERE A.t2field IN (SELECT t2field FROM t2 );
+CREATE PROCEDURE p1 ()
+BEGIN
+SELECT v1field
+FROM v1
+WHERE v1field IN ( SELECT v2field as vf_inner FROM v2 );
+END|
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+CALL p1;
+v1field
+2
+3
+CALL p1;
+v1field
+2
+3
+DROP TABLE t1,t2;
+DROP VIEW v1,v2;
+DROP PROCEDURE p1;
+set SESSION optimizer_switch=@save_optimizer_switch;
+# End of BUG#48834
+
+Bug#49097 subquery with view generates wrong result with
+non-prepared statement
+
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+CREATE TABLE t1 (
+city VARCHAR(50) NOT NULL,
+country_id SMALLINT UNSIGNED NOT NULL
+);
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+CREATE TABLE t2 (
+country_id SMALLINT UNSIGNED NOT NULL,
+country VARCHAR(50) NOT NULL
+);
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'XAmerican Samoa') ;
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+SELECT country_id
+FROM t2
+WHERE LEFT(country,1) = "A"
+);
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+SELECT country_id
+FROM v1
+);
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+PREPARE stmt FROM
+"
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM v1
+);
+";
+execute stmt;
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+deallocate prepare stmt;
+drop table t1, t2;
+drop view v1;
+# End of Bug#49097
+#
+# BUG#38075: Wrong result: rows matching a subquery with outer join not returned
+#
+DROP TABLE IF EXISTS ot1, it1, it2;
+CREATE TABLE it2 (
+int_key int(11) NOT NULL,
+datetime_key datetime NOT NULL,
+KEY int_key (int_key),
+KEY datetime_key (datetime_key)
+);
+INSERT INTO it2 VALUES
+(5,'2002-04-10 14:25:30'), (0,'0000-00-00 00:00:00'),
+(0,'2006-09-14 04:01:02'), (4,'0000-00-00 00:00:00'),
+(8,'0000-00-00 00:00:00'), (5,'0000-00-00 00:00:00'),
+(9,'0000-00-00 00:00:00'), (8,'2007-04-01 11:04:17'),
+(1,'0000-00-00 00:00:00'), (7,'2009-01-12 00:00:00'),
+(0,'2009-06-05 00:00:00'), (3,'2006-02-14 18:06:35'),
+(5,'2006-02-21 07:08:16'), (0,'0000-00-00 00:00:00'),
+(7,'0000-00-00 00:00:00'), (0,'0000-00-00 00:00:00'),
+(0,'2007-02-13 00:00:00'), (1,'0000-00-00 00:00:00'),
+(0,'0000-00-00 00:00:00'), (1,'2003-08-11 00:00:00');
+CREATE TABLE ot1 (
+int_nokey int(11) NOT NULL,
+int_key int(11) NOT NULL,
+KEY int_key (int_key)
+);
+INSERT INTO ot1 VALUES
+(5,0), (3,0), (0,2), (3,0), (1,3), (0,0), (1,7), (7,0), (1,7), (0,7),
+(0,9), (8,2), (4,4), (9,3), (0,9), (2,5), (0,5), (8,0), (5,8), (1,5);
+CREATE TABLE it1 (
+int_nokey int(11) NOT NULL,
+int_key int(11) NOT NULL,
+KEY int_key (int_key)
+);
+INSERT INTO it1 VALUES
+(9,5), (0,4);
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+int_key
+0
+2
+0
+7
+9
+9
+5
+2
+0
+0
+0
+3
+7
+7
+8
+0
+5
+EXPLAIN
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY it1 index NULL int_key 4 NULL 2 Using index; Start temporary
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary; Using join buffer (incremental, BNL join)
+DROP TABLE ot1, it1, it2;
+# End of BUG#38075
+#
+# BUG#31480: Incorrect result for nested subquery when executed via semi join
+#
+create table t1 (a int not null, b int not null);
+create table t2 (c int not null, d int not null);
+create table t3 (e int not null);
+insert into t1 values (1,10);
+insert into t1 values (2,10);
+insert into t1 values (1,20);
+insert into t1 values (2,20);
+insert into t1 values (3,20);
+insert into t1 values (2,30);
+insert into t1 values (4,40);
+insert into t2 values (2,10);
+insert into t2 values (2,20);
+insert into t2 values (4,10);
+insert into t2 values (5,10);
+insert into t2 values (3,20);
+insert into t2 values (2,40);
+insert into t3 values (10);
+insert into t3 values (30);
+insert into t3 values (10);
+insert into t3 values (20);
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select 1 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>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select 1 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
+2
+2
+3
+2
+drop table t1, t2, t3;
+#
+# Bug#48213 Materialized subselect crashes if using GEOMETRY type
+#
+CREATE TABLE t1 (
+pk int,
+a varchar(1),
+b varchar(4),
+c tinyblob,
+d blob,
+e mediumblob,
+f longblob,
+g tinytext,
+h text,
+i mediumtext,
+j longtext,
+k geometry,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff', 'ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))'));
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))'));
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY subselect2 eq_ref unique_key unique_key 13 func 1 1.00
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using MRR
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
+pk
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+pk
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+pk
+1
+2
+EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+pk
+1
+2
+DROP TABLE t1, t2;
+# End of Bug#48213
+#
+# Bug#49198 Wrong result for second call of procedure
+# with view in subselect.
+#
+CREATE TABLE t1 (t1field integer, primary key (t1field));
+CREATE TABLE t2 (t2field integer, primary key (t2field));
+CREATE TABLE t3 (t3field integer, primary key (t3field));
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t1 VALUES(1),(2);
+INSERT INTO t2 VALUES(1),(2);
+INSERT INTO t3 VALUES(1),(2);
+PREPARE stmt FROM
+"
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2);
+";
+EXECUTE stmt;
+t1field
+1
+2
+EXECUTE stmt;
+t1field
+1
+2
+PREPARE stmt FROM
+"
+EXPLAIN
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2)
+ AND t1field IN (SELECT * FROM v3)
+";
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+EXECUTE stmt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.t1field 1 Using index
+DROP TABLE t1, t2, t3;
+DROP VIEW v2, v3;
+# End of Bug#49198
+#
+# Bug#45174: Incorrectly applied equality propagation caused wrong
+# result on a query with a materialized semi-join.
+#
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`varchar_key` varchar(1) NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `varchar_key` (`varchar_key`)
+);
+INSERT INTO `t1` VALUES (11,'m','m'),(12,'j','j'),(13,'z','z'),(14,'a','a'),(15,'',''),(16,'e','e'),(17,'t','t'),(19,'b','b'),(20,'w','w'),(21,'m','m'),(23,'',''),(24,'w','w'),(26,'e','e'),(27,'e','e'),(28,'p','p');
+CREATE TABLE `t2` (
+`varchar_nokey` varchar(1) NOT NULL
+);
+INSERT INTO `t2` VALUES ('v'),('u'),('n'),('l'),('h'),('u'),('n'),('j'),('k'),('e'),('i'),('u'),('n'),('b'),('x'),(''),('q'),('u');
+EXPLAIN EXTENDED SELECT varchar_nokey
+FROM t2
+WHERE ( `varchar_nokey` , `varchar_nokey` ) IN (
+SELECT `varchar_key` , `varchar_nokey`
+FROM t1
+WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
+1 PRIMARY subselect2 eq_ref unique_key unique_key 8 func 1 1.00
+2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
+SELECT varchar_nokey
+FROM t2
+WHERE ( `varchar_nokey` , `varchar_nokey` ) IN (
+SELECT `varchar_key` , `varchar_nokey`
+FROM t1
+WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
+varchar_nokey
+DROP TABLE t1, t2;
+# End of the test for bug#45174.
+#
+# BUG#43768: Prepared query with nested subqueries core dumps on second execution
+#
+create table t1 (
+id int(11) unsigned not null primary key auto_increment,
+partner_id varchar(35) not null,
+t1_status_id int(10) unsigned
+);
+insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"),
+("3", "partner3", "10"), ("4", "partner4", "10");
+create table t2 (
+id int(11) unsigned not null default '0',
+t1_line_id int(11) unsigned not null default '0',
+article_id varchar(20),
+sequence int(11) not null default '0',
+primary key (id,t1_line_id)
+);
+insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
+("2", "2", "sup", "2"), ("2", "3", "sup", "3"),
+("2", "4", "imp", "4"), ("3", "1", "sup", "0"),
+("4", "1", "sup", "0");
+create table t3 (
+id int(11) not null default '0',
+preceeding_id int(11) not null default '0',
+primary key (id,preceeding_id)
+);
+create table t4 (
+user_id varchar(50) not null,
+article_id varchar(20) not null,
+primary key (user_id,article_id)
+);
+insert into t4 values("nicke", "imp");
+prepare stmt from
+'select t1.partner_id
+from t1
+where
+ t1.id in (
+ select pl_inner.id
+ from t2 as pl_inner
+ where pl_inner.article_id in (
+ select t4.article_id from t4
+ where t4.user_id = \'nicke\'
+ )
+ )';
+execute stmt;
+partner_id
+partner2
+execute stmt;
+partner_id
+partner2
+drop table t1,t2,t3,t4;
+#
+# Bug#48623 Multiple subqueries are optimized incorrectly
+#
+CREATE TABLE t1(val VARCHAR(10));
+CREATE TABLE t2(val VARCHAR(10));
+CREATE TABLE t3(val VARCHAR(10));
+INSERT INTO t1 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t2 VALUES('aaa'), ('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t3 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+EXPLAIN
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+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
+1 PRIMARY subselect3 eq_ref unique_key unique_key 14 func 1
+1 PRIMARY subselect2 eq_ref unique_key unique_key 14 func 1
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+AND t1.val IN (SELECT t3.val FROM t3
+WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+val
+aaa
+eee
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+# End of Bug#48623
+#
+# LPBUG#602574: RQG: sql_select.cc:5385: bool greedy_search(JOIN*, table_map, uint,
+# uint): Assertion `join->best_read <
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+CREATE TABLE t2 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+CREATE TABLE t3 (
+varchar_key varchar(1) DEFAULT NULL,
+KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+(NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+WHERE (varchar_key,varchar_key)
+IN (SELECT t1.varchar_key, t2 .varchar_key
+FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+)
+);
+varchar_key
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
+#
+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;
+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;
+UPDATE t2 SET b=11 WHERE a=3;
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='firstmatch=off';
+The following should use a join order of t0,t1,t2, with DuplicateElimination:
+explain
+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 Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 5 Using where; Start temporary
+1 PRIMARY t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join)
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using where; End temporary; Using join buffer (incremental, BKA join)
+SELECT * FROM t0 WHERE t0.a IN
+(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+a
+0
+1
+2
+3
+set optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+# End
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 1
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/r/table_elim.result b/mysql-test/r/table_elim.result
index 395b0be7e34..e635f745ed3 100644
--- a/mysql-test/r/table_elim.result
+++ b/mysql-test/r/table_elim.result
@@ -26,17 +26,17 @@ a
explain select * 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 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
# This will not be eliminated as t2.b is in in order list:
explain select t1.a from t1 left join t2 on t2.a=t1.a order by t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
# This will not be eliminated as t2.b is in group list:
explain select t1.a from t1 left join t2 on t2.a=t1.a group by t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
# This will not be eliminated as t2.b is in the WHERE
explain select t1.a from t1 left join t2 on t2.a=t1.a where t2.b < 3 or t2.b is null;
id select_type table type possible_keys key key_len ref rows Extra
@@ -58,7 +58,7 @@ t0 left join (t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and
t3.a=t1.a) on t0.a=t1.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 4 100.00
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t1`.`a` = `test`.`t0`.`a`)) where 1
# Elimination with aggregate functions
@@ -75,7 +75,7 @@ This must not use elimination:
explain select count(1) from t1 left join t2 on t2.a=t1.a group by t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using index
drop table t0, t1, t2, t3;
create table t0 ( id integer, primary key (id));
create table t1 (
@@ -128,7 +128,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3
This should use facts and a1 tables:
explain extended select id from v1 where attr1 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using where
+1 PRIMARY a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Using MRR
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
@@ -136,7 +136,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` whe
This should use facts, a2 and its subquery:
explain extended select id from v1 where attr2 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using where
+1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using where; Using MRR
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.a2.id 2 100.00 Using index
Warnings:
@@ -156,7 +156,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3
This should use facts and a1 tables:
explain extended select id from v2 where attr1 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using where
+1 PRIMARY a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Using MRR
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
@@ -164,7 +164,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` whe
This should use facts, a2 and its subquery:
explain extended select id from v2 where attr2 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using where
+1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using MRR
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.f.id 2 100.00 Using index
Warnings:
@@ -194,7 +194,7 @@ t2.pk3=t2.pk1+1 and
t2.pk2=t2.pk3+t2.col;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
This must use only t1:
explain select t1.* from t1 left join t2 on t2.pk2=t1.a and
t2.pk1=t2.pk2+1 and
@@ -212,19 +212,19 @@ explain
select t1.* from t1 left join ( t2 left join t3 on t3.pk=t2.col) on t2.col=t1.col;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
explain
select t1.*, t2.* from t1 left join (t2 left join t3 on t3.pk=t2.col) on t2.pk=t1.col;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col 1 Using where
explain select t1.*
from
t1 left join ( t2 left join t3 on t3.pk=t2.col or t3.pk=t2.col)
on t2.col=t1.col or t2.col=t1.col;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
explain select t1.*, t2.*
from
t1 left join
@@ -232,7 +232,7 @@ t1 left join
on t2.pk=t1.col or t2.pk=t1.col;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col 1 Using where
drop table t1, t2, t3;
#
# Check things that look like functional dependencies but really are not
@@ -247,12 +247,12 @@ this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a='foo' collate latin1_general_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
-1 SIMPLE t2 index PRIMARY PRIMARY 10 NULL 2 Using index
+1 SIMPLE t2 index PRIMARY PRIMARY 10 NULL 2 Using where; Using index
this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a=t1.a collate latin1_general_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
-1 SIMPLE t2 index PRIMARY PRIMARY 10 NULL 2 Using index
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
drop table t1,t2;
create table t1 (a int primary key);
insert into t1 values (1),(2);
@@ -262,12 +262,12 @@ this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using index
-1 SIMPLE t2 index PRIMARY PRIMARY 10 NULL 2 Using index
+1 SIMPLE t2 index PRIMARY PRIMARY 10 NULL 2 Using where; Using index
this must not use table elimination:
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 4 NULL 2 Using index
-1 SIMPLE t2 index PRIMARY PRIMARY 10 NULL 2 Using index
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
drop table t1, t2;
create table t1 (a char(10) primary key);
insert into t1 values ('foo'),('bar');
@@ -276,7 +276,7 @@ insert into t2 values ('foo'),('bar');
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
-1 SIMPLE t2 ref a a 3 test.t1.a 2
+1 SIMPLE t2 ref a a 3 test.t1.a 2 Using where
drop table t1, t2;
#
# check UPDATE/DELETE that look like they could be eliminated
@@ -322,19 +322,19 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select t1.a from t1 left join t2 on t2.pk=t1.a or t2.b<t1.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Using where
explain select t1.a from t1 left join t2 on t2.b<t1.b or t2.pk=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Using where
explain select t1.a from t1 left join t2 on t2.pk between 10 and 20;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select t1.a from t1 left join t2 on t2.pk between 0.5 and 1.5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select t1.a from t1 left join t2 on t2.pk between 10 and 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
@@ -347,7 +347,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select t1.a from t1 left join t2 on TRUE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 index NULL PRIMARY 4 NULL 2 Using index
+1 SIMPLE t2 index NULL PRIMARY 4 NULL 2 Using where; Using index
explain select t1.a from t1 left join t3 on t3.pk1=t1.a and t3.pk2 IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
@@ -388,7 +388,7 @@ on (t2.pk=t2.c and t2.b=t1.a and t2.c=t1.b) or
where t1.d=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where
explain
select t1.*
from
@@ -405,7 +405,7 @@ select t1.*
from t1 left join t2 on t2.pk=3 or t2.pk= 4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain
select t1.*
from t1 left join t2 on t2.pk=3 or t2.pk= 3;
@@ -416,7 +416,7 @@ select t1.*
from t1 left join t2 on (t2.pk=3 and t2.b=3) or (t2.pk= 4 and t2.b=3);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using MRR
drop table t1, t2;
#
# LPBUG#523593: Running RQG optimizer_no_subquery crashes MariaDB
diff --git a/mysql-test/r/table_elim_debug.result b/mysql-test/r/table_elim_debug.result
index b059baffa89..ae49b1433fd 100644
--- a/mysql-test/r/table_elim_debug.result
+++ b/mysql-test/r/table_elim_debug.result
@@ -10,7 +10,7 @@ set optimizer_switch='table_elimination=off';
explain select t1.a 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 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using index
set optimizer_switch='table_elimination=on';
explain select t1.a from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index dab1d78ba27..8c07668cf58 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -207,6 +207,7 @@ id select_type table type possible_keys key key_len ref rows Extra
Warnings:
Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 1
SELECT * FROM t1 WHERE a = '0000-00-00';
a
0000-00-00
@@ -214,6 +215,7 @@ a
Warnings:
Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 1
SELECT * FROM t2 WHERE a = '0000-00-00';
a
0000-00-00
@@ -245,6 +247,7 @@ id select_type table type possible_keys key key_len ref rows Extra
Warnings:
Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 1
SELECT * FROM t1 WHERE a = '1000-00-00';
a
1000-00-00
@@ -252,6 +255,7 @@ a
Warnings:
Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 1
SELECT * FROM t2 WHERE a = '1000-00-00';
a
1000-00-00
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 9b18f250d21..76edaea45a1 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -514,10 +514,9 @@ select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
-Note 1003 select '1' AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` where <in_optimizer>('1',<exists>(select 1 from `test`.`t1` `x1` where 0))
+Note 1003 select '1' AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where (('2007-04-25 18:30:22' = 0))
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id cur_date
@@ -526,10 +525,9 @@ select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
-Note 1003 select '1' AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` where <in_optimizer>('1',<exists>(select 1 from `test`.`t2` `x1` where 0))
+Note 1003 select '1' AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where (('2007-04-25' = 0))
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id cur_date
@@ -539,11 +537,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; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`id`,<exists>(select 1 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
@@ -551,11 +549,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; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 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/union.result b/mysql-test/r/union.result
index 054f416bfd4..cd3091b072b 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -542,12 +542,12 @@ explain (select * from t1 where a=1 and b=10) union (select straight_join t1.a,t
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 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index
-2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer
+2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
explain (select * from t1 where a=1) union (select * from t1 where b=1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
-2 UNION t1 ref b b 5 const 1 Using where
+2 UNION t1 ref b b 5 const 1
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
drop table t1,t2;
create table t1 ( id int not null auto_increment, primary key (id) ,user_name text );
@@ -1632,7 +1632,7 @@ ORDER BY (SELECT a FROM t2 WHERE b = 12);
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 UNION t1 ALL NULL NULL NULL NULL 2 100.00
-3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index b2065ed20d1..3615276a56c 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1415,8 +1415,8 @@ a a b
explain extended select * from t3 left join v3 on (t3.a = v3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
create view v1 (a) as select a from t1;
@@ -1430,8 +1430,8 @@ a a b
explain extended select * from t3 left join v4 on (t3.a = v4.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);";
@@ -2132,12 +2132,12 @@ INSERT INTO t1 VALUES (2, 'foo2');
INSERT INTO t1 VALUES (1, 'foo1');
SELECT * FROM v1;
id f
-1 foo1
2 foo2
+1 foo1
SELECT * FROM v1;
id f
-1 foo1
2 foo2
+1 foo1
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (pk int PRIMARY KEY, b int);
@@ -2342,15 +2342,15 @@ CREATE VIEW v2 AS SELECT t3.* FROM t1,t3 WHERE t1.a=t3.a;
EXPLAIN SELECT t1.* FROM t1 JOIN t2 WHERE t1.a=t2.a AND t1.b=t2.b AND t1.a=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
-1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index
+1 SIMPLE t2 ref a a 10 const,test.t1.b 1 Using index
EXPLAIN SELECT * FROM v1 WHERE a=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
-1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index
+1 SIMPLE t2 ref a a 10 const,test.t1.b 1 Using index
EXPLAIN SELECT * FROM v2 WHERE a=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
-1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ref a a 5 const 1 Using index
+1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
DROP VIEW v1,v2;
DROP TABLE t1,t2,t3;
create table t1 (f1 int);
diff --git a/mysql-test/suite/binlog/t/binlog_stm_row.test b/mysql-test/suite/binlog/t/binlog_stm_row.test
index 29b0a69330d..47d9cbbbfb6 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_row.test
+++ b/mysql-test/suite/binlog/t/binlog_stm_row.test
@@ -60,7 +60,7 @@ let $wait_condition=
--echo # con1
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE
- state = "Locked" and info = "INSERT INTO t2 VALUES (3)";
+ state = "Table Lock" and info = "INSERT INTO t2 VALUES (3)";
--source include/wait_condition.inc
SELECT RELEASE_LOCK('Bug#34306');
--connection con2
diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc
index b1c1130cbdf..e06c5f081f5 100644
--- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc
+++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc
@@ -368,13 +368,13 @@ echo
;
connection default;
echo
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = "Table Lock".
;
let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE INFO IS NOT NULL AND STATE = 'Locked';
+ WHERE INFO IS NOT NULL AND STATE = "Table Lock";
--source include/wait_condition.inc
#
-# Expect to see the state 'Locked' for the third connection because the SELECT
+# Expect to see the state "Table Lock" for the third connection because the SELECT
# collides with the WRITE TABLE LOCK.
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
@@ -423,10 +423,10 @@ echo
;
connection default;
echo
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = "Table Lock".
;
let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE INFO IS NOT NULL AND STATE = 'Locked';
+ WHERE INFO IS NOT NULL AND STATE = "Table Lock";
--source include/wait_condition.inc
echo
# Expect result:
diff --git a/mysql-test/suite/handler/aria.result b/mysql-test/suite/handler/aria.result
index a912a2559e3..89595c0a62a 100644
--- a/mysql-test/suite/handler/aria.result
+++ b/mysql-test/suite/handler/aria.result
@@ -150,11 +150,18 @@ handler t2 read a>=(16) limit 2,2;
a b
17 ddd
18 eee
+select * from t1 where a>=16 limit 2,2;
+a b
+17 ddd
+18 eee
handler t2 read a last limit 3;
a b
22 iii
21 hhh
20 ggg
+handler t2 read a=(16) limit 1,3;
+a b
+16 xxx
handler t2 read a=(19);
a b
19 fff
@@ -194,6 +201,127 @@ a b
alter table t1 engine = Aria;
handler t2 read first;
ERROR 42S02: Unknown table 't2' in HANDLER
+handler t1 open;
+handler t1 read a=(16) limit 1,3;
+a b
+16 xxx
+flush tables;
+handler t1 read a=(16) limit 1,3;
+a b
+16 xxx
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=16,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+16 xxx
+set @a=16,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=16,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+16 ccc
+16 xxx
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(11);
+a b
+14 aaa
+set @a=3;
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+17 ddd
+execute stmt using @a;
+a b
+18 eee
+19 fff
+19 yyy
+execute stmt using @a;
+a b
+20 ggg
+21 hhh
+22 iii
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+22 iii
+21 hhh
+20 ggg
+execute stmt using @a;
+a b
+19 yyy
+19 fff
+18 eee
+execute stmt using @a;
+a b
+17 ddd
+16 xxx
+16 ccc
+execute stmt using @a;
+a b
+14 aaa
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b=(?,?)';
+set @a=14, @b='aaa';
+execute stmt using @a,@b;
+a b
+14 aaa
+set @a=14, @b='not found';
+execute stmt using @a,@b;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b=(1+?) limit 10';
+set @a=15;
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a>=(?) where a < ? limit 5';
+set @a=15, @b=20;
+execute stmt using @a,@b;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+19 fff
+execute stmt using @a,@b;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+19 fff
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=16;
+execute stmt using @a;
+a b
+16 ccc
+alter table t1 add c int;
+execute stmt using @a;
+ERROR 42S02: Unknown table 't1' in HANDLER
+deallocate prepare stmt;
+handler t1 close;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?)';
+flush tables;
+set @a=16;
+execute stmt using @a;
+ERROR HY000: Prepared statement needs to be re-prepared
+deallocate prepare stmt;
+handler t1 close;
handler t1 open as t2;
drop table t1;
create table t1 (a int not null);
diff --git a/mysql-test/suite/handler/handler.inc b/mysql-test/suite/handler/handler.inc
index 48ed2ce0b8a..1ed80cce200 100644
--- a/mysql-test/suite/handler/handler.inc
+++ b/mysql-test/suite/handler/handler.inc
@@ -89,8 +89,9 @@ handler t2 read a prev limit 10;
handler t2 read a>=(16) limit 4;
handler t2 read a>=(16) limit 2,2;
+select * from t1 where a>=16 limit 2,2;
handler t2 read a last limit 3;
-
+handler t2 read a=(16) limit 1,3;
handler t2 read a=(19);
handler t2 read a=(19) where b="yyy";
@@ -115,6 +116,79 @@ eval alter table t1 engine = $engine_type;
--error 1109
handler t2 read first;
+handler t1 open;
+handler t1 read a=(16) limit 1,3;
+flush tables;
+handler t1 read a=(16) limit 1,3;
+handler t1 close;
+
+#
+# Test with prepared statements
+#
+
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=16,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+set @a=16,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+set @a=16,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(11);
+set @a=3;
+execute stmt using @a;
+execute stmt using @a;
+execute stmt using @a;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+execute stmt using @a;
+execute stmt using @a;
+execute stmt using @a;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read b=(?,?)';
+set @a=14, @b='aaa';
+execute stmt using @a,@b;
+set @a=14, @b='not found';
+execute stmt using @a,@b;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read b=(1+?) limit 10';
+set @a=15;
+execute stmt using @a;
+execute stmt using @a;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read a>=(?) where a < ? limit 5';
+set @a=15, @b=20;
+execute stmt using @a,@b;
+execute stmt using @a,@b;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read a=(?)';
+set @a=16;
+execute stmt using @a;
+alter table t1 add c int;
+--error 1109
+execute stmt using @a;
+deallocate prepare stmt;
+--error 1109
+handler t1 close;
+
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?)';
+flush tables;
+set @a=16;
+--error ER_NEED_REPREPARE
+execute stmt using @a;
+deallocate prepare stmt;
+handler t1 close;
+
#
# DROP TABLE / ALTER TABLE
#
diff --git a/mysql-test/suite/handler/innodb.result b/mysql-test/suite/handler/innodb.result
index 83ce270612d..a8700c8b4bb 100644
--- a/mysql-test/suite/handler/innodb.result
+++ b/mysql-test/suite/handler/innodb.result
@@ -150,11 +150,18 @@ handler t2 read a>=(16) limit 2,2;
a b
17 ddd
18 eee
+select * from t1 where a>=16 limit 2,2;
+a b
+17 ddd
+18 eee
handler t2 read a last limit 3;
a b
22 iii
21 hhh
20 ggg
+handler t2 read a=(16) limit 1,3;
+a b
+16 xxx
handler t2 read a=(19);
a b
19 fff
@@ -194,6 +201,127 @@ a b
alter table t1 engine = InnoDB;
handler t2 read first;
ERROR 42S02: Unknown table 't2' in HANDLER
+handler t1 open;
+handler t1 read a=(16) limit 1,3;
+a b
+16 xxx
+flush tables;
+handler t1 read a=(16) limit 1,3;
+a b
+16 xxx
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=16,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+16 xxx
+set @a=16,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=16,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+16 ccc
+16 xxx
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(11);
+a b
+14 aaa
+set @a=3;
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+17 ddd
+execute stmt using @a;
+a b
+18 eee
+19 fff
+19 yyy
+execute stmt using @a;
+a b
+20 ggg
+21 hhh
+22 iii
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+22 iii
+21 hhh
+20 ggg
+execute stmt using @a;
+a b
+19 yyy
+19 fff
+18 eee
+execute stmt using @a;
+a b
+17 ddd
+16 xxx
+16 ccc
+execute stmt using @a;
+a b
+14 aaa
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b=(?,?)';
+set @a=14, @b='aaa';
+execute stmt using @a,@b;
+a b
+14 aaa
+set @a=14, @b='not found';
+execute stmt using @a,@b;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b=(1+?) limit 10';
+set @a=15;
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a>=(?) where a < ? limit 5';
+set @a=15, @b=20;
+execute stmt using @a,@b;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+19 fff
+execute stmt using @a,@b;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+19 fff
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=16;
+execute stmt using @a;
+a b
+16 ccc
+alter table t1 add c int;
+execute stmt using @a;
+ERROR 42S02: Unknown table 't1' in HANDLER
+deallocate prepare stmt;
+handler t1 close;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?)';
+flush tables;
+set @a=16;
+execute stmt using @a;
+ERROR HY000: Prepared statement needs to be re-prepared
+deallocate prepare stmt;
+handler t1 close;
handler t1 open as t2;
drop table t1;
create table t1 (a int not null);
diff --git a/mysql-test/suite/handler/myisam.result b/mysql-test/suite/handler/myisam.result
index bd356d6e81d..5423e9ce814 100644
--- a/mysql-test/suite/handler/myisam.result
+++ b/mysql-test/suite/handler/myisam.result
@@ -150,11 +150,18 @@ handler t2 read a>=(16) limit 2,2;
a b
17 ddd
18 eee
+select * from t1 where a>=16 limit 2,2;
+a b
+17 ddd
+18 eee
handler t2 read a last limit 3;
a b
22 iii
21 hhh
20 ggg
+handler t2 read a=(16) limit 1,3;
+a b
+16 xxx
handler t2 read a=(19);
a b
19 fff
@@ -194,6 +201,127 @@ a b
alter table t1 engine = MyISAM;
handler t2 read first;
ERROR 42S02: Unknown table 't2' in HANDLER
+handler t1 open;
+handler t1 read a=(16) limit 1,3;
+a b
+16 xxx
+flush tables;
+handler t1 read a=(16) limit 1,3;
+a b
+16 xxx
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=16,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+16 xxx
+set @a=16,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=16,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+16 ccc
+16 xxx
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(11);
+a b
+14 aaa
+set @a=3;
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+17 ddd
+execute stmt using @a;
+a b
+18 eee
+19 fff
+19 yyy
+execute stmt using @a;
+a b
+20 ggg
+21 hhh
+22 iii
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+22 iii
+21 hhh
+20 ggg
+execute stmt using @a;
+a b
+19 yyy
+19 fff
+18 eee
+execute stmt using @a;
+a b
+17 ddd
+16 xxx
+16 ccc
+execute stmt using @a;
+a b
+14 aaa
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b=(?,?)';
+set @a=14, @b='aaa';
+execute stmt using @a,@b;
+a b
+14 aaa
+set @a=14, @b='not found';
+execute stmt using @a,@b;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b=(1+?) limit 10';
+set @a=15;
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+execute stmt using @a;
+a b
+16 ccc
+16 xxx
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a>=(?) where a < ? limit 5';
+set @a=15, @b=20;
+execute stmt using @a,@b;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+19 fff
+execute stmt using @a,@b;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+19 fff
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=16;
+execute stmt using @a;
+a b
+16 ccc
+alter table t1 add c int;
+execute stmt using @a;
+ERROR 42S02: Unknown table 't1' in HANDLER
+deallocate prepare stmt;
+handler t1 close;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?)';
+flush tables;
+set @a=16;
+execute stmt using @a;
+ERROR HY000: Prepared statement needs to be re-prepared
+deallocate prepare stmt;
+handler t1 close;
handler t1 open as t2;
drop table t1;
create table t1 (a int not null);
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 345da7a0163..b8d02ecbc78 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1219,7 +1219,7 @@ count(*)
623
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using where
+1 SIMPLE t1 range c c 5 NULL # Using index condition; Using MRR
update t1 set c=a;
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
@@ -1914,7 +1914,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -2090,7 +2090,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using where
+1 SIMPLE t1 ref v v 303 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result
index c6c775afc9f..e44f2aec093 100644
--- a/mysql-test/suite/innodb/r/innodb_gis.result
+++ b/mysql-test/suite/innodb/r/innodb_gis.result
@@ -403,7 +403,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index 08fb0bdfe2e..0fcfa34da7c 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -187,7 +187,7 @@ min(7)
explain select min(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
-1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
select min(7) from t2i join t1i;
min(7)
NULL
@@ -203,7 +203,7 @@ max(7)
explain select max(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
-1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
select max(7) from t2i join t1i;
max(7)
NULL
@@ -356,7 +356,7 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
-1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
+1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using index
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
@@ -1426,12 +1426,15 @@ DROP TABLE t1;
#
create table t1 (a bit(1) not null,b int) engine=myisam;
create table t2 (c int) engine=innodb;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
explain
select b from t1 where a not in (select b from t1,t2 group by a) group by a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1
+set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
End of 5.0 tests
CREATE TABLE `t2` (
@@ -2645,3 +2648,95 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2, t1;
+#
+# Bug #663818: wrong result when BNLH is used
+#
+CREATE TABLE t1(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1), (2), (11), (12), (13), (14),
+(15), (16), (17), (18), (19);
+CREATE TABLE t2(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1), (10), (11), (12), (13), (14),
+(15), (16), (17), (18), (19), (20), (21);
+SET SESSION join_buffer_size=10000;
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT t1.pk FROM t1,t2
+WHERE t1.pk = t2.pk AND t2.pk <> 8;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 11 Using where; Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; Using join buffer (flat, BNLH join)
+SELECT t1.pk FROM t1,t2
+WHERE t1.pk = t2.pk AND t2.pk <> 8;
+pk
+1
+11
+12
+13
+14
+15
+16
+17
+18
+19
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT t1.pk FROM t1,t2
+WHERE t1.pk = t2.pk AND t2.pk <> 8;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 11 Using where; Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index
+SELECT t1.pk FROM t1,t2
+WHERE t1.pk = t2.pk AND t2.pk <> 8;
+pk
+1
+11
+12
+13
+14
+15
+16
+17
+18
+19
+DROP TABLE t1,t2;
+SET SESSION join_cache_level=DEFAULT;
+SET SESSION join_buffer_size=DEFAULT;
+#
+# Bug#668644: HAVING + ORDER BY
+#
+CREATE TABLE t1 (
+pk int NOT NULL PRIMARY KEY, i int DEFAULT NULL,
+INDEX idx (i)
+) ENGINE=INNODB;
+INSERT INTO t1 VALUES
+(6,-1636630528),(2,-1097924608),(1,6),(3,6),(4,1148715008),(5,1541734400);
+CREATE TABLE t2 (
+i int DEFAULT NULL,
+pk int NOT NULL PRIMARY KEY,
+INDEX idx (i)
+) ENGINE= INNODB;
+INSERT INTO t2 VALUES
+(-1993998336,20),(-1036582912,1),(-733413376,5),(-538247168,16),
+(-514260992,4),(-249561088,9),(1,2),(1,6),(2,10),(2,19),(4,17),
+(5,14),(5,15),(6,8),(7,13),(8,18),(9,11),(9,12),(257425408,7),
+(576061440,3);
+EXPLAIN
+SELECT t1 .i AS f FROM t1, t2
+WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
+HAVING f > 7
+ORDER BY f;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
+1 SIMPLE t2 ref idx idx 5 test.t1.pk 1 Using index
+SELECT t1 .i AS f FROM t1, t2
+WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
+HAVING f > 7
+ORDER BY f;
+f
+1148715008
+1541734400
+1541734400
+DROP TABLE t1, t2;
+End of 5.3 tests
diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test
index 177dabdc3e1..cec4085e9a5 100644
--- a/mysql-test/suite/innodb/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test
@@ -851,10 +851,8 @@ drop table t1;
--echo #
-
--echo End of 5.1 tests
-
--echo #
--echo # Test for bug #39932 "create table fails if column for FK is in different
--echo # case than in corr index".
@@ -871,3 +869,73 @@ create table t2 (fk int, key x (fk),
constraint x foreign key (FK) references t1 (PK)) engine=InnoDB;
show create table t2;
drop table t2, t1;
+
+--echo #
+--echo # Bug #663818: wrong result when BNLH is used
+--echo #
+
+CREATE TABLE t1(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+ (1), (2), (11), (12), (13), (14),
+ (15), (16), (17), (18), (19);
+CREATE TABLE t2(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+ (1), (10), (11), (12), (13), (14),
+ (15), (16), (17), (18), (19), (20), (21);
+
+SET SESSION join_buffer_size=10000;
+
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT t1.pk FROM t1,t2
+ WHERE t1.pk = t2.pk AND t2.pk <> 8;
+SELECT t1.pk FROM t1,t2
+ WHERE t1.pk = t2.pk AND t2.pk <> 8;
+
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT t1.pk FROM t1,t2
+ WHERE t1.pk = t2.pk AND t2.pk <> 8;
+SELECT t1.pk FROM t1,t2
+ WHERE t1.pk = t2.pk AND t2.pk <> 8;
+
+DROP TABLE t1,t2;
+
+SET SESSION join_cache_level=DEFAULT;
+SET SESSION join_buffer_size=DEFAULT;
+
+--echo #
+--echo # Bug#668644: HAVING + ORDER BY
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL PRIMARY KEY, i int DEFAULT NULL,
+ INDEX idx (i)
+) ENGINE=INNODB;
+INSERT INTO t1 VALUES
+ (6,-1636630528),(2,-1097924608),(1,6),(3,6),(4,1148715008),(5,1541734400);
+
+CREATE TABLE t2 (
+ i int DEFAULT NULL,
+ pk int NOT NULL PRIMARY KEY,
+ INDEX idx (i)
+) ENGINE= INNODB;
+INSERT INTO t2 VALUES
+ (-1993998336,20),(-1036582912,1),(-733413376,5),(-538247168,16),
+ (-514260992,4),(-249561088,9),(1,2),(1,6),(2,10),(2,19),(4,17),
+ (5,14),(5,15),(6,8),(7,13),(8,18),(9,11),(9,12),(257425408,7),
+ (576061440,3);
+
+EXPLAIN
+SELECT t1 .i AS f FROM t1, t2
+ WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
+ HAVING f > 7
+ ORDER BY f;
+SELECT t1 .i AS f FROM t1, t2
+ WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
+ HAVING f > 7
+ ORDER BY f;
+
+DROP TABLE t1, t2;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result
index c4b718bd975..60ddfa749b1 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb.result
@@ -1,3 +1,5 @@
+set optimizer_switch='index_condition_pushdown=off';
+set @@optimizer_use_mrr=disable;
drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest;
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
@@ -3239,3 +3241,5 @@ Variable_name Value
Handler_update 1
Variable_name Value
Handler_delete 1
+set optimizer_switch='index_condition_pushdown=default';
+set @@optimizer_use_mrr=default;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_gis.result b/mysql-test/suite/innodb_plugin/r/innodb_gis.result
index c6c775afc9f..e44f2aec093 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_gis.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_gis.result
@@ -403,7 +403,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
-1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
index 1aee85b5288..b652847486e 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
@@ -187,7 +187,7 @@ min(7)
explain select min(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
-1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
select min(7) from t2i join t1i;
min(7)
NULL
@@ -203,7 +203,7 @@ max(7)
explain select max(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
-1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
select max(7) from t2i join t1i;
max(7)
NULL
@@ -356,7 +356,7 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
-1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
+1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using index
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
@@ -1426,12 +1426,15 @@ DROP TABLE t1;
#
create table t1 (a bit(1) not null,b int) engine=myisam;
create table t2 (c int) engine=innodb;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
explain
select b from t1 where a not in (select b from t1,t2 group by a) group by a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1
+set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
End of 5.0 tests
CREATE TABLE `t2` (
diff --git a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test
index 1b840f696c1..3415745c2c5 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb.test
@@ -19,6 +19,9 @@ let $MYSQLD_DATADIR= `select @@datadir`;
let collation=utf8_unicode_ci;
--source include/have_collation.inc
+set optimizer_switch='index_condition_pushdown=off';
+set @@optimizer_use_mrr=disable;
+
# Save the original values of some variables in order to be able to
# estimate how much they have changed during the tests. Previously this
# test assumed that e.g. rows_deleted is 0 here and after deleting 23
@@ -2543,6 +2546,9 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
-- enable_query_log
+set optimizer_switch='index_condition_pushdown=default';
+set @@optimizer_use_mrr=default;
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result
index 3f9a4b636d1..0e58cc3b65d 100644
--- a/mysql-test/suite/maria/r/maria.result
+++ b/mysql-test/suite/maria/r/maria.result
@@ -381,21 +381,21 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 4 test.t2.a 3
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
-1 SIMPLE t1 ref b b 5 test.t2.b 1 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 2 Using where
+1 SIMPLE t1 ref b b 5 test.t2.b 1
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
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 4 Using index condition; Using MRR
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 4 Using index condition; Using MRR
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 Using where
+1 SIMPLE t1 ref c,c_2 c 5 const 1
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
@@ -1131,7 +1131,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -1307,7 +1307,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using where
+1 SIMPLE t1 ref v v 303 const # Using index condition
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/README.txt b/mysql-test/suite/optimizer_unfixed_bugs/README.txt
new file mode 100644
index 00000000000..ddf65555ce2
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/README.txt
@@ -0,0 +1,29 @@
+Putting testcases here
+~~~~~~~~~~~~~~~~~~~~~~
+
+When you work on re-verifying or re-classifying a bug (not fixing it),
+it's a good idea to put the mtr-parsable '.test' testcase here.
+Benefits:
+1) tests downloaded from the bugs db are sometimes close to
+mtr-parsable but not completely (for example if they contain
+/* comment */); when you re-verify or re-classify you run the test so
+may have to make it mtr-parsable; if you then put it in this suite,
+the developer who will work on this bug in a few weeks or months will
+not have to re-do the same download&fix, she/he can instead reuse your
+work.
+2) Others can see how their own work influences many unsolved
+bugs, by running this suite. If they find that they fix a bug in this
+suite, we won't later wonder "how come this bug doesn't happen
+anymore, what fixed it?".
+3) One can also run this suite with certain switches to see how they
+influence unsolved bugs:
+./mtr --suite=optimizer_unfixed_bugs \
+--mysqld=--optimizer_switch="firstmatch=off"
+
+Adding tests to this suite
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+One test file per bug, named bugNNNNN.test.
+Put the correct (not current and buggy) result file in r/, so that "[ pass ]"
+in mtr will mean that a bug looks like fixed.
+When you have fixed a bug, remove files from this suite.
+t/bug45219.test is an example.
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug36981.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug36981.result
new file mode 100644
index 00000000000..1b0a9c636e7
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug36981.result
@@ -0,0 +1,9 @@
+set session debug="+d,optimizer_innodb_icp";
+create table `t1` (`c1` char(1) default null,`c2` char(10) default null,
+key (`c1`))
+engine=innodb default charset=latin1;
+insert into `t1` values ('3',null);
+select * from `t1` where `c1`='3' for update;
+c1 c2
+3 NULL
+drop table `t1`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug40992.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug40992.result
new file mode 100644
index 00000000000..9c30b32e1e5
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug40992.result
@@ -0,0 +1,15 @@
+#
+# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
+#
+set session debug="+d,optimizer_innodb_icp";
+CREATE TABLE t (
+dummy INT PRIMARY KEY,
+a INT UNIQUE,
+b int
+) ENGINE=InnoDB;
+INSERT INTO t VALUES (1,1,1),(3,3,3),(5,5,5);
+SELECT * FROM t WHERE a > 2 FOR UPDATE;
+dummy a b
+3 3 3
+5 5 5
+DROP TABLE t;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41029.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41029.result
new file mode 100644
index 00000000000..d65feac5a0b
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41029.result
@@ -0,0 +1,34 @@
+select @default_binlog_format:=@@global.binlog_format;
+@default_binlog_format:=@@global.binlog_format
+STATEMENT
+set global binlog_format=row;
+set session debug="+d,optimizer_innodb_ds_mrr";
+set autocommit=0;
+use test;
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+create table t1 (dummy int primary key, a int unique, b int) engine=innodb;
+insert into t1 values(1,1,1),(3,3,3),(5,5,5);
+commit;
+set session transaction isolation level repeatable read;
+select @@tx_isolation;
+@@tx_isolation
+REPEATABLE-READ
+start transaction;
+select * from t1 where a > 2 for update;
+dummy a b
+3 3 3
+5 5 5
+use test;
+set autocommit=0;
+start transaction;
+select 1;
+1
+1
+insert into t1 values(2,2,2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+rollback;
+rollback;
+drop table t1;
+set global binlog_format=@default_binlog_format;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb-innodb.result
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb-innodb.result
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb.result
new file mode 100644
index 00000000000..94b024a9c8f
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb.result
@@ -0,0 +1,1108 @@
+set optimizer_use_mrr='disable';
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1.result
new file mode 100644
index 00000000000..94b024a9c8f
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1.result
@@ -0,0 +1,1108 @@
+set optimizer_use_mrr='disable';
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb-innodb.result
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb-innodb.result
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb.result
new file mode 100644
index 00000000000..58654984e33
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2-innodb.result
@@ -0,0 +1,1107 @@
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2.result
new file mode 100644
index 00000000000..58654984e33
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra2.result
@@ -0,0 +1,1107 @@
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM d2.t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM d3.t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb-innodb.result
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb-innodb.result
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb.result
new file mode 100644
index 00000000000..4f9cbfb554c
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3-innodb.result
@@ -0,0 +1,984 @@
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3.result
new file mode 100644
index 00000000000..4f9cbfb554c
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra3.result
@@ -0,0 +1,984 @@
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb-innodb.result
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb-innodb.result
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb.result
new file mode 100644
index 00000000000..0ff634de0f3
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4-innodb.result
@@ -0,0 +1,984 @@
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4.result
new file mode 100644
index 00000000000..0ff634de0f3
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra4.result
@@ -0,0 +1,984 @@
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+3 3
+4 4
+5 5
+SELECT * FROM t2 ORDER BY c1;
+c1 c2
+12 1
+15 6
+SELECT * FROM t3 ORDER BY c1;
+c1 c2
+21 11
+22 11
+23 13
+24 14
+25 15
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996.result
new file mode 100644
index 00000000000..e42f61376c4
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996.result
@@ -0,0 +1,8 @@
+set session debug="+d,optimizer_innodb_icp";
+drop table if exists `t1`;
+Warnings:
+Note 1051 Unknown table 't1'
+create table `t1` (`c` bigint, key(`c`),`a` int)engine=innodb;
+insert into `t1` values(2,2);
+delete `t1` from `t1` `a`, `t1` where `a`.`a`=`t1`.`c` ;
+drop table `t1`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug42991.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug42991.result
new file mode 100644
index 00000000000..0daa91361c2
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug42991.result
@@ -0,0 +1,252 @@
+set session debug="+d,optimizer_innodb_icp";
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `table5`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+CREATE TABLE `table5` (
+`col0` mediumtext,
+`col1` varchar(90) DEFAULT NULL,
+`col2` tinytext,
+`col3` time DEFAULT NULL,
+`col4` tinyint(1) DEFAULT NULL,
+`col5` tinytext,
+`col6` tinyint(1) DEFAULT NULL,
+`col7` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+`col8` tinyblob,
+`col9` tinyint(4) DEFAULT NULL,
+`col10` year(4) DEFAULT NULL,
+`col11` set('test1','test2','test3') DEFAULT NULL,
+`col12` text,
+`col13` char(248) DEFAULT NULL,
+`col14` bigint(20) DEFAULT NULL,
+`col15` text,
+`col16` tinyint(4) DEFAULT NULL,
+`col17` decimal(10,0) DEFAULT NULL,
+`col18` set('test1','test2','test3') DEFAULT NULL,
+`col19` varchar(255) DEFAULT NULL,
+`col20` float DEFAULT NULL,
+`col21` int(11) DEFAULT NULL,
+`col22` text,
+`col23` tinyint(1) DEFAULT NULL,
+`col24` decimal(10,0) NOT NULL DEFAULT '0',
+`col25` double DEFAULT NULL,
+`col26` float DEFAULT NULL,
+`col27` tinyblob,
+`col28` decimal(10,0) DEFAULT NULL,
+`col29` mediumblob,
+`col30` date DEFAULT NULL,
+`col31` longtext,
+`col32` date DEFAULT NULL,
+`col33` float DEFAULT NULL,
+`col34` bigint(20) DEFAULT NULL,
+`col35` tinytext,
+`col36` mediumtext,
+`col37` time DEFAULT NULL,
+`col38` int(11) DEFAULT NULL,
+`col39` tinyint(4) DEFAULT NULL,
+`col40` set('test1','test2','test3') DEFAULT NULL,
+`col41` char(130) DEFAULT NULL,
+`col42` smallint(6) DEFAULT NULL,
+`col43` int(11) DEFAULT NULL,
+`col44` mediumtext,
+`col45` varchar(126) DEFAULT NULL,
+`col46` int(11) DEFAULT NULL,
+`col47` double DEFAULT NULL,
+`col48` bigint(20) DEFAULT NULL,
+`col49` mediumtext,
+`col50` tinyblob,
+`col51` mediumint(9) DEFAULT NULL,
+`col52` text,
+`col53` varchar(208) DEFAULT NULL,
+`col54` varchar(207) DEFAULT NULL,
+`col55` decimal(10,0) DEFAULT NULL,
+`col56` datetime DEFAULT NULL,
+`col57` enum('test1','test2','test3') DEFAULT NULL,
+`col58` decimal(10,0) DEFAULT NULL,
+`col59` tinyblob,
+`col60` varchar(73) DEFAULT NULL,
+`col61` mediumtext,
+`col62` tinyblob,
+`col63` datetime DEFAULT NULL,
+`col64` decimal(10,0) DEFAULT NULL,
+`col65` mediumint(9) DEFAULT NULL,
+`col66` datetime DEFAULT NULL,
+`col67` decimal(10,0) DEFAULT NULL,
+`col68` tinyint(4) DEFAULT NULL,
+`col69` varchar(58) DEFAULT NULL,
+`col70` decimal(10,0) DEFAULT NULL,
+`col71` mediumtext,
+`col72` date DEFAULT NULL,
+`col73` time DEFAULT NULL,
+`col74` double DEFAULT NULL,
+`col75` decimal(10,0) DEFAULT NULL,
+`col76` mediumblob,
+`col77` double DEFAULT NULL,
+`col78` year(4) DEFAULT NULL,
+`col79` year(4) DEFAULT NULL,
+`col80` varchar(255) DEFAULT NULL,
+`col81` blob,
+`col82` bigint(20) DEFAULT NULL,
+`col83` enum('test1','test2','test3') DEFAULT NULL,
+`col84` decimal(10,0) DEFAULT NULL,
+`col85` set('test1','test2','test3') DEFAULT NULL,
+`col86` mediumtext,
+`col87` varchar(255) DEFAULT NULL,
+`col88` time DEFAULT NULL,
+`col89` enum('test1','test2','test3') DEFAULT NULL,
+`col90` decimal(10,0) DEFAULT NULL,
+`col91` float DEFAULT NULL,
+`col92` datetime DEFAULT NULL,
+`col93` tinytext,
+`col94` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+`col95` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+`col96` text,
+`col97` double DEFAULT NULL,
+`col98` varchar(198) DEFAULT NULL,
+`col99` time DEFAULT NULL,
+`col100` tinyint(4) DEFAULT NULL,
+`col101` bigint(20) DEFAULT NULL,
+`col102` varchar(255) DEFAULT NULL,
+`col103` varchar(255) DEFAULT NULL,
+`col104` mediumint(9) DEFAULT NULL,
+`col105` mediumtext,
+`col106` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+`col107` smallint(6) DEFAULT NULL,
+`col108` decimal(10,0) DEFAULT NULL,
+`col109` decimal(10,0) DEFAULT NULL,
+`col110` float DEFAULT NULL,
+`col111` decimal(10,0) DEFAULT NULL,
+`col112` double DEFAULT NULL,
+`col113` tinytext,
+`col114` float DEFAULT NULL,
+`col115` varchar(7) DEFAULT NULL,
+`col116` longtext,
+`col117` date DEFAULT NULL,
+`col118` bigint(20) DEFAULT NULL,
+`col119` text,
+`col120` bigint(20) DEFAULT NULL,
+`col121` blob,
+`col122` char(110) DEFAULT NULL,
+`col123` decimal(10,0) DEFAULT NULL,
+`col124` mediumblob,
+`col125` decimal(10,0) DEFAULT NULL,
+`col126` decimal(10,0) DEFAULT NULL,
+`col127` tinyint(1) DEFAULT NULL,
+`col128` time DEFAULT NULL,
+`col129` tinyblob,
+`col130` tinyblob,
+`col131` date DEFAULT NULL,
+`col132` int(11) DEFAULT NULL,
+`col133` varchar(123) DEFAULT NULL,
+`col134` char(238) DEFAULT NULL,
+`col135` varchar(225) DEFAULT NULL,
+`col136` longtext,
+`col137` varchar(255) DEFAULT NULL,
+`col138` double DEFAULT NULL,
+`col139` tinyblob,
+`col140` datetime DEFAULT NULL,
+`col141` tinytext,
+`col142` varchar(255) DEFAULT NULL,
+`col143` bigint(20) DEFAULT NULL,
+`col144` varchar(236) DEFAULT NULL,
+`col145` text,
+`col146` year(4) DEFAULT NULL,
+`col147` decimal(10,0) DEFAULT NULL,
+`col148` text,
+`col149` mediumblob,
+`col150` tinyint(4) DEFAULT NULL,
+`col151` tinyint(1) DEFAULT NULL,
+`col152` varchar(72) DEFAULT NULL,
+`col153` int(11) DEFAULT NULL,
+`col154` varchar(165) DEFAULT NULL,
+`col155` tinyint(4) DEFAULT NULL,
+`col156` mediumtext,
+`col157` double DEFAULT NULL,
+`col158` time DEFAULT NULL,
+`col159` mediumblob,
+`col160` varchar(255) DEFAULT NULL,
+`col161` datetime DEFAULT NULL,
+`col162` double DEFAULT NULL,
+`col163` blob,
+`col164` enum('test1','test2','test3') DEFAULT NULL,
+`col165` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+`col166` date DEFAULT NULL,
+`col167` tinyblob,
+`col168` tinyblob,
+`col169` varchar(255) DEFAULT NULL,
+`col170` datetime DEFAULT NULL,
+`col171` bigint(20) DEFAULT NULL,
+`col172` varchar(30) DEFAULT NULL,
+`col173` longtext,
+`col174` time DEFAULT NULL,
+`col175` float DEFAULT NULL,
+PRIMARY KEY (`col24`),
+KEY `idx0` (`col16`,`col156`(139),`col97`,`col120`),
+KEY `idx1` (`col24`,`col0`(108)),
+KEY `idx2` (`col117`,`col173`(34),`col132`,`col82`),
+KEY `idx3` (`col2`(86)),
+KEY `idx4` (`col2`(43)),
+KEY `idx5` (`col83`,`col35`(87),`col111`),
+KEY `idx6` (`col6`,`col134`,`col92`),
+KEY `idx7` (`col56`),
+KEY `idx8` (`col30`,`col53`,`col129`(66)),
+KEY `idx9` (`col53`,`col113`(211),`col32`,`col15`(75)),
+KEY `idx10` (`col34`),
+KEY `idx11` (`col126`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
+LOCK TABLES `table5` WRITE;
+/*!40000 ALTER TABLE `table5` DISABLE KEYS */;
+INSERT INTO `table5` VALUES ('referenda','hermaphroditism','superable','00:00:00',-128,NULL,-128,'0000-00-00 00:00:00',NULL,-128,1901,NULL,'blandly',NULL,6541,'unsuspectingly',NULL,'7250','',NULL,-31358,26248,'Kilmarnock\'s',127,'-27305',28987,NULL,NULL,'-30388','utilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitarians','0000-00-00','Agincourt','0000-00-00',-28063,27242,'readies',NULL,'00:00:00',NULL,-128,'',NULL,NULL,18719,NULL,NULL,14038,17275,NULL,'gait\'s','honeymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'sho',8860,NULL,'demigod','outpulling',NULL,'1904-01-17 09:51:06','test1','-18008','grotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'s','Oakleil\'s','Shostakovich','indiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscre','2076-10-05 02:05:43','29914',-18885,'2088-05-25 13:36:33','25',-128,'Bob','-14559','ammeter','0000-00-00','00:00:00',-29756,NULL,'digressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigression',-23894,1963,1915,'SadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadye',NULL,NULL,'','17512','','anaphylaxis\'s','chiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schise','50:11:25','test1','-13685',-18328,'2020-01-19 22:04:54',NULL,'1988-05-10 10:30:56','0000-00-00 00:00:00','Birdie\'s',-27746,NULL,'179:19:25',-128,24141,'radiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparen','ingroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'sing',18950,'Beaulieu','0000-00-00 00:00:00',-23421,'-2865',NULL,NULL,NULL,NULL,'vandalizes',-24683,'interop','Apis\'s','0000-00-00',19745,'Volgograd\'s',-15194,NULL,'Binni','4540','phylumphylumphylumphylum','-25781',NULL,-128,'406:37:03','posthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthastepos','manneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristman','0000-00-00',19774,'shariah',NULL,'aquarelle','homographic',NULL,-18959,'thoroughfarethoroughfarethoroughfarethoroughfarethoroughfarethoroughfare','2000-09-05 03:33:50','Baptlsta','Witt\'sWitt\'sWitt\'sWitt\'sWitt\'sWitt\'sWitt\'sWitt\'s',4727,NULL,'posting',2119,'32416',NULL,'charredcharredcharredcharredcharredcharredcharredcharredcharredcharred',-128,NULL,'Rollin\'s',NULL,NULL,127,'waviness\'s',11164,'424:28:18','FaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucher','stalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'s','1901-01-29 13:48:34',-31988,'Dyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'s','','2022-01-01 21:14:30','0000-00-00','conventionalistconventionalistconventionalistconventionalistconventionalistconventionalistconventionalistconventionalist','mirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnesses','tessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stes','2028-05-21 04:56:16',NULL,'Hasid','Hardecanute','00:00:00',-3782);
+Warnings:
+Warning 1265 Data truncated for column 'col83' at row 1
+Warning 1265 Data truncated for column 'col164' at row 1
+INSERT INTO `table5` VALUES ('hemoglobin\'s','Toffey\'s','Juvenal','00:00:00',-128,'harmonicon',-128,'2004-02-13 09:45:46',NULL,NULL,1911,'','Tananarive\'s',NULL,30666,'spiniferous',127,'30675','','Frederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFr',30388,4769,'Erymanthus\'s',127,'-20972',NULL,-17111,'explosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosiveness','-28154','magnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'s','0000-00-00','removes','0000-00-00',16859,NULL,NULL,'Moishe\'s','00:00:00',NULL,NULL,NULL,'hyperform\'s',30540,-26603,'soporific',NULL,NULL,19264,-14618,NULL,'zootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszo',5654,'intermezzi','Atkins\'s','hieroglyphically','15885','2068-10-19 12:22:30','','4972','apatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapa','severeness','pleaders',NULL,'2070-09-15 17:21:46','15245',-18313,'1934-01-01 01:20:15','-3488',127,'Delawarian','14952','foregathers','0000-00-00','00:00:00',-27837,'7143','madhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'s',-17163,1951,2054,'raffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraf','REMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMs',3607,'','-17633','',NULL,NULL,'806:59:31','test1','-29600',20301,'1985-10-09 17:57:25',NULL,'0000-00-00 00:00:00','0000-00-00 00:00:00','Perseid',-32117,'constructer\'s','612:19:03',127,NULL,'overdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingove','Carlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCa',24868,'preamble','0000-00-00 00:00:00',-7582,'-865','-14488',6884,'-24713',NULL,'topknot\'s',18469,NULL,'histrionism\'s','0000-00-00',31715,'Dag',14543,'wooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'s','tightest',NULL,'aquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'s','15603',NULL,-128,'640:34:17','acetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumaceta','torridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridl','9323-05-13',-28292,'Barnaul\'s',NULL,'slanginesses','supernova',NULL,20804,NULL,'2020-10-05 12:00:38','rive',NULL,-31498,'considerateness\'s','nevus\'s',1901,'-12956','fashioner\'s','unfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'s',-128,127,'nephralgia\'s',13881,'sciatically',NULL,'Tuesday',21227,'00:00:00','halocarbons','duvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduv','2075-01-21 10:49:44',-19735,'snubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubs','test1','0000-00-00 00:00:00','0000-00-00','kiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkib',NULL,'connoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseurscon','1953-01-23 17:36:00',NULL,'Principal',NULL,'316:28:48',NULL);
+Warnings:
+Warning 1265 Data truncated for column 'col57' at row 1
+Warning 1265 Data truncated for column 'col83' at row 1
+INSERT INTO `table5` VALUES (NULL,'Annmarie','intangibleness\'s','00:00:00',-128,'transmogrify',127,'0000-00-00 00:00:00',NULL,127,2093,'','enamored','refired',-21296,'neglectful',127,'-9992','',NULL,NULL,3583,'Lockheed\'s',127,'-15717',-29743,-16280,'embouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembou','-24875',NULL,'0000-00-00',NULL,'0000-00-00',30124,20356,'drinkable','obscenity','00:00:00',NULL,127,'',NULL,-16664,NULL,'unmoor','Vaughan\'s',30457,-16509,-10049,'squeamishness','encirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencir',-16460,'abatement\'s',NULL,'expatriate','-28670','1925-05-15 11:44:20','','-3762','DelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDel','Skerl\'s','unmatched',NULL,'1980-01-11 16:02:04','25917',18187,'2001-07-26 13:48:08','-28706',127,'gimme','8807',NULL,'0000-00-00','00:00:00',7666,'21762','drawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacks',16131,2031,2077,'subjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysub','Argenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'s',NULL,'','-17090','','fobs','humiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliat','221:02:40','','-1107',4624,'1926-05-11 03:35:52',NULL,'2037-05-13 05:02:44','0000-00-00 00:00:00','Heddie\'s',-6554,NULL,'00:00:00',127,NULL,'lxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlx','RawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawley',6613,'Beaufort','0000-00-00 00:00:00',12214,NULL,'25469',-26474,'12062',NULL,'physiographer',26382,'cosmogo','deportment\'s','0000-00-00',17492,'propretor\'s',NULL,'zingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzing','Suzetta','25513','tearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkers','21613',NULL,-128,'108:58:18','sporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallyspo','Monera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'','0000-00-00',18776,'diffractometer',NULL,'crawls','Inglebert','unguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableun',18112,'melanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanis','1940-05-18 13:21:00','artlessly','blotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblots',6476,NULL,'Bartlett',2143,NULL,'thaumaturge\'s','Hazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'s',127,127,'Winthorpe',-29765,'idiocrasy\'s',NULL,'sandcastles',-9852,'281:41:52','Volny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'s','protagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagon','2076-01-04 15:01:57',NULL,'auscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultations','','0000-00-00 00:00:00','0000-00-00','limenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimen','accommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatingly',NULL,'2018-01-01 05:48:54',17404,NULL,NULL,'195:36:50',24658);
+Warnings:
+Warning 1265 Data truncated for column 'col57' at row 1
+Warning 1265 Data truncated for column 'col83' at row 1
+Warning 1265 Data truncated for column 'col89' at row 1
+Warning 1265 Data truncated for column 'col164' at row 1
+INSERT INTO `table5` VALUES ('caddishly',NULL,'Kotah','00:00:00',-128,'tailoring',127,'0000-00-00 00:00:00','trustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustie',-128,1967,NULL,NULL,'parallelisms',NULL,NULL,127,NULL,'',NULL,NULL,-513,NULL,NULL,'-14518',NULL,-22393,'AngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAng','32257','regalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregaling','0000-00-00','newspaperwoman','0000-00-00',24845,-17741,'impassiveness','Antillean','00:00:00',-13615,-128,'','gantries',-27983,-6070,'Benetton','aridest',NULL,21574,-25634,'McWilliams\'s','burrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowe',18947,NULL,NULL,'surrealistic',NULL,'1954-07-07 08:58:49','test1','-11714','ExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExEx','administrants','Oxycontin','interpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterper','1914-05-28 05:15:03','3942',NULL,'2046-09-07 18:16:36','3220',127,'arising','18472','anacolutha','0000-00-00','613:15:45',NULL,'-23969',NULL,18979,2031,1975,'AlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcesti','septicitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticities',-25058,'',NULL,'','Kulturkampf','pollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpol','00:00:00','','12283',2881,'1926-12-10 09:24:42','Darken\'s','2034-12-21 15:59:00','0000-00-00 00:00:00',NULL,NULL,NULL,'305:05:06',127,NULL,'feudalityfeudality','Merrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMer',-25733,'borak','0000-00-00 00:00:00',-11465,'877',NULL,-1029,'5107',NULL,'Balaton\'s',NULL,'Martian','miserliness','0000-00-00',14689,'catchment',18457,'billet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'s','humerus\'s','24741',NULL,NULL,'-19233',-128,'00:00:00','fashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfas','judiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjud','0000-00-00',15972,'Letrice\'s','hydrographer',NULL,'Federica','evidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevi',4115,'pshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspsh','1924-10-15 16:31:18','Hamlet','trowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'',-3485,'galvanized',NULL,1924,'-22877','unfired','inchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'s',-128,-128,'VHF',-5304,NULL,127,'glossator',16348,'213:10:59','',NULL,'1946-01-11 17:25:16',262,'DoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDouty','test1','0000-00-00 00:00:00','0000-00-00',NULL,'feasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasibl','contortionisticcontortionisticcontortionisticcontortionisticcontortionisticcontortionisticcontortionistic','2027-06-09 07:56:16',6909,'tessitura','indefensible','00:00:00',-6628);
+Warnings:
+Warning 1265 Data truncated for column 'col83' at row 1
+Warning 1265 Data truncated for column 'col89' at row 1
+INSERT INTO `table5` VALUES ('bassoonist\'s',NULL,'refastens','114:27:50',127,'unrestricted',127,'2032-01-13 11:11:22','abstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'s',NULL,1955,'','Hodosh','allocates',-5067,'Cenac\'s',-128,'31546',NULL,'impassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassab',-30347,292,'Sandi\'s',NULL,'-12402',8206,NULL,'encircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircl','6346','ArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentinians','0000-00-00','Riehl\'s','0000-00-00',NULL,5580,'planets',NULL,'58:35:07',317,127,'','gender',-19514,7112,'Pissaro','relevantly',28777,-21818,-17111,'shoddiness\'s',NULL,NULL,'flee','Boatwright\'s','restrict','12537','2096-04-25 08:45:21','test1','-4613','quagga','masterstroke\'s','overcheck\'s',NULL,'1981-10-14 18:30:02','21097',-26481,'2065-07-11 02:13:44',NULL,NULL,'bathroom','-29833','gracelessness\'s','0000-00-00','09:44:40',-7368,NULL,'applecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'s',-21077,2015,2039,'cascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scas','nervingnervingnervingnervingnervingnervingnervingnervingnervingnerving',22043,'','5740','','mustached','actin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'s','00:00:00','test1','13871',-22276,'1956-01-05 15:08:47','slimline','0000-00-00 00:00:00','0000-00-00 00:00:00','royally',NULL,'mako','51:54:53',NULL,NULL,'deliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'s','DOADOADOADOADOADOADOADOADOADOADOADOADOA',-16244,'Fayette\'s','2020-06-21 05:34:18',-24353,'24097','-28819',12278,'-2365',21322,'stumps',-61,NULL,'subpoena\'s','0000-00-00',31242,'knicker',23567,NULL,'Cathar','29557','thallusthallusthallusthallusthallusthallusthallusthallusthallusthallus','26114',NULL,-128,'00:00:00','salmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsal','shiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshive','0000-00-00',-3152,'syndesis','misbrands','Smiga','stagnation\'s','nonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricno',NULL,NULL,'1988-09-11 14:33:03',NULL,'provokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglypr',25510,'thunderpeal\'s','hierology',1932,'7729','Fahrenheit','metathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'s',NULL,-128,'sinfonia\'s',-6293,'proactive',127,NULL,-24751,'00:00:00','woodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopper','Constantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'','1997-01-01 22:40:48',NULL,'MatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlick','test1','2000-12-17 11:19:08','0000-00-00',NULL,'cosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmica','Loesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesc','2078-07-25 04:56:08',10472,NULL,NULL,'345:12:02',-13120);
+Warnings:
+Warning 1265 Data truncated for column 'col83' at row 1
+INSERT INTO `table5` VALUES ('segmentation\'s','shapelessness\'s','coagulators','127:46:24',-128,NULL,127,'0000-00-00 00:00:00','seekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingsee',NULL,2085,'','indent','flyblown',NULL,'Alegre',-128,'-27917','','DesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDes',2473,NULL,'screwball\'s',NULL,'-4861',-7088,-30734,'tambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintam',NULL,NULL,'0000-00-00','Dorcia','0000-00-00',-25745,-1237,'Shoifet\'s','sarsaparillas','21:11:41',31612,-128,'','subway\'s',-5032,-30369,'preventives','lyre',7995,21283,13197,'chippies','rubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubig',19050,'orch','semiliterates','Gerome',NULL,'2058-12-26 21:29:19','',NULL,'dyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdya','Dukas\'s','Christiania','polyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvale','1920-05-23 14:07:00','672',NULL,'1956-06-27 12:15:00','-22658',NULL,'holograph\'s',NULL,'gutsy','0000-00-00','00:00:00',-9558,'1148','fainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfains',NULL,2023,2132,'Balmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBal','overdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdo',-24707,'test1','-13970','','tensility','BuddieBuddieBuddieBuddieBuddieBuddieBuddieBuddieBuddieBuddie','00:00:00','','580',25115,'2000-07-01 09:01:36','apprentice','1992-01-01 08:55:38','0000-00-00 00:00:00','premunire',24664,NULL,'821:21:05',NULL,-29284,'rapidestrapidestrapidestrapidestrapidestrapidestrapidest','convectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorcon',-3808,'intuitively','0000-00-00 00:00:00',-22296,NULL,'2802',28786,NULL,NULL,'loanword',-12107,'deodori','strophe','0000-00-00',-11013,'undeclared',-8513,'sinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'s','peloria\'s','14940','blushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblush','30550','11566',127,'00:00:00','worktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'swo','looker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'s','5657-05-11',23094,'onerousness','bearer','censured','Shoemaker','mulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomul',5930,'ZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoust','1953-04-28 11:55:44','consulted','invalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinv',-27798,'carnauba\'s','Wilson',1963,NULL,'On\'s','leisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurely',NULL,-128,NULL,17674,'Queenstown\'s',-128,'convertors',1776,'576:20:59',NULL,'allegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriall','2097-10-02 08:41:26',31057,'AfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikaners','test1','0000-00-00 00:00:00','0000-00-00','backwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbac',NULL,NULL,'1932-10-01 18:49:04',12985,NULL,'leukocytes','603:54:26',-22488);
+Warnings:
+Warning 1265 Data truncated for column 'col57' at row 1
+Warning 1265 Data truncated for column 'col89' at row 1
+INSERT INTO `table5` VALUES ('Frasquito\'s','unsatisfactory','jetted','00:00:00',NULL,'Merlin\'s',127,'0000-00-00 00:00:00',NULL,NULL,1998,'','decomposer','Commons',-14813,'oversimplification\'s',NULL,'-5368','','engirdengirdengirdengirdengirdengirdengirdengirdengird',-13627,14305,'frontally',127,'18421',-32295,NULL,NULL,'21841',NULL,'0000-00-00','cytology','2424-00-17',-30542,-17621,'octarchy\'s','outfoxed','00:00:00',27469,-128,'','Kamat\'s',-24130,-5948,'riband','Betsy',NULL,-18769,NULL,NULL,'Serafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSeraf',NULL,'disconcerting',NULL,'whirly','-20343','2020-07-01 12:09:36','','-26975','antiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticant',NULL,'ecumenically','utilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilize','1952-08-01 17:53:28','7903',-5633,'2024-03-17 13:46:59','-5474',127,'Malmö\'s',NULL,NULL,'0000-00-00','571:58:00',17287,'26711','alphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetize',-15158,2001,1997,'hobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithob','Campinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'s',-5693,'test1','3741','','Audrye\'s','monstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymo','00:00:00','test1','-21023',4693,'1998-01-06 04:41:40','Silastic\'s','0000-00-00 00:00:00','0000-00-00 00:00:00','Hedelman\'s',-30080,'normalization\'s','00:00:00',NULL,8197,NULL,NULL,NULL,'nudism\'s','2005-04-13 00:31:55',29046,'8992','11992',NULL,'-1685',-11453,'mythology\'s',26185,'Pyrenea','Pedrick\'s','0000-00-00',27436,'shots',NULL,'discordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscords','bayonet','-7217','scriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscripts',NULL,'17182',NULL,'628:49:55','nunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenuncle',NULL,'0000-00-00',-17444,'celestite\'s','Adars','Hispaniola','Mesopotamians','agglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutin',31998,'electrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistriesele','2005-09-09 23:41:06','bastinaded',NULL,-10763,'impetuosity\'s','xenogenesis\'s',1947,'-29913',NULL,'taxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomies',NULL,NULL,'internees',28697,'Kharkov\'s',NULL,'Swabia',18366,'00:00:00','delayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayer','circusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycir','2066-02-13 14:27:00',-28405,NULL,'test1','0000-00-00 00:00:00','0000-00-00','heterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotr','enchondromaenchondromaenchondromaenchondromaenchondromaenchondromaenchondromaenchondroma','AryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAry','2090-10-13 10:03:05',NULL,NULL,'Yucatan','285:37:51',7627);
+Warnings:
+Warning 1265 Data truncated for column 'col57' at row 1
+/*!40000 ALTER TABLE `table5` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+select * from `table5` where (col2 <= '6566-06-15' AND col24 <> 'd') group by `col83` order by `col83` desc ;
+col0 col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13 col14 col15 col16 col17 col18 col19 col20 col21 col22 col23 col24 col25 col26 col27 col28 col29 col30 col31 col32 col33 col34 col35 col36 col37 col38 col39 col40 col41 col42 col43 col44 col45 col46 col47 col48 col49 col50 col51 col52 col53 col54 col55 col56 col57 col58 col59 col60 col61 col62 col63 col64 col65 col66 col67 col68 col69 col70 col71 col72 col73 col74 col75 col76 col77 col78 col79 col80 col81 col82 col83 col84 col85 col86 col87 col88 col89 col90 col91 col92 col93 col94 col95 col96 col97 col98 col99 col100 col101 col102 col103 col104 col105 col106 col107 col108 col109 col110 col111 col112 col113 col114 col115 col116 col117 col118 col119 col120 col121 col122 col123 col124 col125 col126 col127 col128 col129 col130 col131 col132 col133 col134 col135 col136 col137 col138 col139 col140 col141 col142 col143 col144 col145 col146 col147 col148 col149 col150 col151 col152 col153 col154 col155 col156 col157 col158 col159 col160 col161 col162 col163 col164 col165 col166 col167 col168 col169 col170 col171 col172 col173 col174 col175
+Warnings:
+Warning 1366 Incorrect decimal value: 'd' for column 'col24' at row 1
+Warning 1366 Incorrect decimal value: 'd' for column 'col24' at row 1
+drop table `table5`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43101.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43101.result
new file mode 100644
index 00000000000..af0262e1ce6
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43101.result
@@ -0,0 +1,31 @@
+CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY
+KEY(c1), UNIQUE INDEX(c2));
+insert into t1 values('-838:59:59','-838:59:59','2009-01-21');
+insert into t1 values('00:00:00','00:00:00','2009-01-09');
+insert into t1 values('00:00:11','00:00:11','2009-01-20');
+insert into t1 values('00:00:12','00:00:12','2009-01-13');
+insert into t1 values('00:00:45','00:00:45','2009-01-07');
+insert into t1 values('00:11:12','00:11:12','2009-01-19');
+insert into t1 values('00:12:30','00:12:30','2009-01-23');
+insert into t1 values('00:12:34','00:12:34','2009-01-14');
+insert into t1 values('01:23:00','01:23:00','2009-01-03');
+insert into t1 values('08:03:02','08:03:02','2009-01-18');
+insert into t1 values('08:29:45',NULL,'2009-02-01');
+insert into t1 values('09:00:45','09:00:45','2009-01-24');
+insert into t1 values('09:36:00','09:36:00','2009-01-25');
+insert into t1 values('10:00:00','10:00:00','2009-01-06');
+insert into t1 values('10:11:12','10:11:12','2009-01-11');
+insert into t1 values('10:22:33','10:22:33','2009-01-02');
+insert into t1 values('11:11:12','11:11:12','2009-01-12');
+insert into t1 values('11:11:27','11:11:27','2009-01-17');
+insert into t1 values('12:34:56','12:34:56','2009-01-01');
+insert into t1 values('12:34:58','12:34:58','2009-01-15');
+insert into t1 values('12:35:56','12:35:56','2009-01-16');
+insert into t1 values('491:22:33','491:22:33','2009-01-04');
+insert into t1 values('825:23:00','825:23:00','2009-01-05');
+insert into t1 values('838:59:59','838:59:59','2009-01-21');
+SELECT * FROM t1 WHERE c2 <> NULL ORDER BY c2 DESC;
+c1 c2 c3
+SELECT * FROM t1 WHERE c2 <> NULL ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3
+drop table t1;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43249.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43249.result
new file mode 100644
index 00000000000..c60a830b899
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43249.result
@@ -0,0 +1,11 @@
+set session debug="+d,optimizer_innodb_icp";
+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');
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c2 LIMIT 2;
+c1 c2 c3
+08:29:45 NULL 2009-02-01
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c2 LIMIT 2;
+c1 c2 c3
+08:29:45 NULL 2009-02-01
+drop table `t1`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43360.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43360.result
new file mode 100644
index 00000000000..a6f4fcd0018
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43360.result
@@ -0,0 +1,44 @@
+#
+# Bug#43360 - Server crash with a simple multi-table update
+#
+set session debug="+d,optimizer_innodb_icp";
+CREATE TABLE t1 (
+a CHAR(2) NOT NULL PRIMARY KEY,
+b VARCHAR(20) NOT NULL,
+KEY (b)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+a CHAR(2) NOT NULL PRIMARY KEY,
+b VARCHAR(20) NOT NULL,
+KEY (b)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+('AB','MySQLAB'),
+('JA','Sun Microsystems'),
+('MS','Microsoft'),
+('IB','IBM- Inc.'),
+('GO','Google Inc.');
+INSERT INTO t2 VALUES
+('AB','Sweden'),
+('JA','USA'),
+('MS','United States of America'),
+('IB','North America'),
+('GO','South America');
+Warnings:
+Warning 1265 Data truncated for column 'b' at row 3
+UPDATE t1,t2 SET t1.b=UPPER(t1.b) WHERE t1.b LIKE 'United%';
+SELECT * FROM t1;
+a b
+GO Google Inc.
+IB IBM- Inc.
+MS Microsoft
+AB MySQLAB
+JA Sun Microsystems
+SELECT * FROM t2;
+a b
+IB North America
+GO South America
+AB Sweden
+MS United States of Ame
+JA USA
+DROP TABLE t1,t2;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43448.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43448.result
new file mode 100644
index 00000000000..9c9d99837cc
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43448.result
@@ -0,0 +1,30 @@
+#
+# Bug#43448 - Server crashes on multi table delete with Innodb
+#
+set session debug="+d,optimizer_innodb_icp";
+CREATE TABLE t1 (
+id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+t CHAR(12)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+id2 INT NOT NULL,
+t CHAR(12)
+) ENGINE=InnoDB;
+CREATE TABLE t3(
+id3 INT NOT NULL,
+t CHAR(12),
+INDEX(id3)
+) ENGINE=InnoDB;
+SELECT COUNT(*) FROM t1 WHERE id1 > 90;
+COUNT(*)
+10
+SELECT COUNT(*) FROM t2 WHERE id2 > 90;
+COUNT(*)
+50
+SELECT COUNT(*) FROM t3 WHERE id3 > 90;
+COUNT(*)
+500
+DELETE t1, t2, t3
+FROM t1, t2, t3
+WHERE t1.id1 = t2.id2 AND t2.id2 = t3.id3 AND t1.id1 > 5;
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result
new file mode 100644
index 00000000000..562fe4785d5
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result
@@ -0,0 +1,98 @@
+set storage_engine=innodb;
+set @save_time_zone= @@time_zone;
+set time_zone='+03:00';
+set session debug="+d,optimizer_innodb_icp";
+CREATE TABLE t1(c1 TIMESTAMP NOT NULL, c2 TIMESTAMP NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1), UNIQUE INDEX(c2));
+INSERT INTO t1 VALUES('98-12-31 11:30:45','98.12.31 11+30+45','98-12-31 11:30:45','98.12.31 11+30+45'),('98/12/30 11*30*45','98@12@30 11^30^45','98/12/30 11*30*45','98@12@30 11^30^45'),('98-12-29','98.12.29','98-12-29','98.12.29'),('98/12/28','98@12@28','98/12/28','98@12@28');
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+INSERT INTO t1 VALUES('20070523091528','070523091528','20070524091528','070524091528'),('20070525','070525','20070526','070526');
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+INSERT INTO t1 VALUES(19830905132800,830905132800,19830906132800,830906132800),(19830907,830907,19830908,830908);
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+SET TIMESTAMP=1233216687;
+INSERT INTO t1 VALUES(NOW(),CURRENT_DATE,NOW(),CURRENT_DATE);
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+INSERT INTO t1 VALUES('2008-01-01',NULL,'08-01-02','08/01/03');
+INSERT INTO t1(c1,c2) VALUES('08/01/17',NULL);
+DELETE FROM t1 WHERE c1='08/01/17' AND c2 IS NULL;
+INSERT INTO t1 VALUES('','','08-01-04','08/01/05') /* Inserts zero dates for '' strings */;
+Warnings:
+Warning 1265 Data truncated for column 'c1' at row 1
+Warning 1265 Data truncated for column 'c2' at row 1
+SELECT * FROM t1;
+c1 c2 c3 c4
+0000-00-00 00:00:00 0000-00-00 00:00:00 2008-01-04 2008-01-05 00:00:00
+1983-09-05 13:28:00 1983-09-05 13:28:00 1983-09-06 1983-09-06 13:28:00
+1983-09-07 00:00:00 1983-09-07 00:00:00 1983-09-08 1983-09-08 00:00:00
+1998-12-28 00:00:00 1998-12-28 00:00:00 1998-12-28 1998-12-28 00:00:00
+1998-12-29 00:00:00 1998-12-29 00:00:00 1998-12-29 1998-12-29 00:00:00
+1998-12-30 11:30:45 1998-12-30 11:30:45 1998-12-30 1998-12-30 11:30:45
+1998-12-31 11:30:45 1998-12-31 11:30:45 1998-12-31 1998-12-31 11:30:45
+2007-05-23 09:15:28 2007-05-23 09:15:28 2007-05-24 2007-05-24 09:15:28
+2007-05-25 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 00:00:00 2009-01-29 2009-01-29 00:00:00
+INSERT IGNORE INTO t1(c1,c2) VALUES('20070525','20070527') /* doesnt throw error */;
+INSERT IGNORE INTO t1(c1,c2) VALUES(19840905,830907) /* doesnt throw error */;
+SELECT * FROM t1 WHERE c1='20070527' /* Returns no rows */;
+c1 c2 c3 c4
+INSERT INTO t1(c1) VALUES('20070525') ON DUPLICATE KEY UPDATE c1='20070527';
+SELECT * FROM t1 WHERE c1='20070527' /* Returns 1 row with c1=2007-05-27 */;
+c1 c2 c3 c4
+2007-05-27 00:00:00 2007-05-25 00:00:00 2007-05-26 2007-05-26 00:00:00
+SELECT * FROM t1 WHERE c1=19830909 AND c2=830910 /* Returns no rows */;
+c1 c2 c3 c4
+INSERT INTO t1(c1,c2) VALUES(19840905,830907) ON DUPLICATE KEY UPDATE c1=19830909,c2=830910;
+SELECT * FROM t1 WHERE c1=19830909 AND c2=830910 /* Returns 1 row */;
+c1 c2 c3 c4
+1983-09-09 00:00:00 1983-09-10 00:00:00 1983-09-08 1983-09-08 00:00:00
+INSERT INTO t1 SET c1='1999-01-01',c2='1999-01-01';
+SELECT * FROM t1 WHERE c1='1999-01-01' AND c2='1999-01-01' /* Returns 1 row with values for other column as NULL */;
+c1 c2 c3 c4
+1999-01-01 00:00:00 1999-01-01 00:00:00 NULL NULL
+INSERT INTO t1 VALUES('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02'),('1990-01-01 00:00:01','2000-01-01 00:00:01','2009-01-03','2009-01-04'),('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06');
+DELETE FROM t1 WHERE c1=NOW() /* because the row with current timestamp exists */;
+INSERT INTO t1 VALUES(NULL,NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+SELECT * FROM t1 WHERE c1 IS NULL /* returns no rows */;
+c1 c2 c3 c4
+SELECT * FROM t1 WHERE c1=NOW() /* returns 1 row */;
+c1 c2 c3 c4
+2009-01-29 11:11:27 2009-01-29 11:11:27 2009-01-29 2009-01-29 11:11:27
+SELECT * FROM t1;
+c1 c2 c3 c4
+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
+1983-09-05 13:28:00 1983-09-05 13:28:00 1983-09-06 1983-09-06 13:28:00
+1983-09-09 00:00:00 1983-09-10 00:00:00 1983-09-08 1983-09-08 00:00:00
+1990-01-01 00:00:01 2000-01-01 00:00:01 2009-01-03 2009-01-04 00:00:00
+1998-12-28 00:00:00 1998-12-28 00:00:00 1998-12-28 1998-12-28 00:00:00
+1998-12-29 00:00:00 1998-12-29 00:00:00 1998-12-29 1998-12-29 00:00:00
+1998-12-30 11:30:45 1998-12-30 11:30:45 1998-12-30 1998-12-30 11:30:45
+1998-12-31 11:30:45 1998-12-31 11:30:45 1998-12-31 1998-12-31 11:30:45
+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;
+set time_zone= @save_time_zone;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43618.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43618.result
new file mode 100644
index 00000000000..4350c912a31
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43618.result
@@ -0,0 +1,57 @@
+set @save_time_zone= @@time_zone;
+set time_zone='+03:00';
+CREATE TABLE t1(c1 TIMESTAMP NOT NULL, c2 TIMESTAMP NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1), UNIQUE INDEX(c2));
+INSERT INTO t1 VALUES('98-12-31 11:30:45','98.12.31 11+30+45','98-12-31 11:30:45','98.12.31 11+30+45'),('98/12/30 11*30*45','98@12@30 11^30^45','98/12/30 11*30*45','98@12@30 11^30^45'),('98-12-29','98.12.29','98-12-29','98.12.29'),('98/12/28','98@12@28','98/12/28','98@12@28');
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+INSERT INTO t1 VALUES('20070523091528','070523091528','20070524091528','070524091528'),('20070525','070525','20070526','070526');
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+INSERT INTO t1 VALUES(19830905132800,830905132800,19830906132800,830906132800),(19830907,830907,19830908,830908);
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+SET TIMESTAMP=1233216687;
+INSERT INTO t1 VALUES(NOW(),CURRENT_DATE,NOW(),CURRENT_DATE);
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+INSERT INTO t1 VALUES('2008-01-01',NULL,'08-01-02','08/01/03');
+INSERT INTO t1(c1,c2) VALUES('08/01/17',NULL);
+DELETE FROM t1 WHERE c1='08/01/17' AND c2 IS NULL;
+INSERT INTO t1 VALUES('','','08-01-04','08/01/05') /* Inserts zero dates for '' strings */;
+Warnings:
+Warning 1265 Data truncated for column 'c1' at row 1
+Warning 1265 Data truncated for column 'c2' at row 1
+INSERT INTO t1 VALUES('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02'),('1990-01-01 00:00:01','2000-01-01 00:00:01','2009-01-03','2009-01-04'),('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06');
+SELECT * FROM t1;
+c1 c2 c3 c4
+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
+1983-09-05 13:28:00 1983-09-05 13:28:00 1983-09-06 1983-09-06 13:28:00
+1983-09-07 00:00:00 1983-09-07 00:00:00 1983-09-08 1983-09-08 00:00:00
+1990-01-01 00:00:01 2000-01-01 00:00:01 2009-01-03 2009-01-04 00:00:00
+1998-12-28 00:00:00 1998-12-28 00:00:00 1998-12-28 1998-12-28 00:00:00
+1998-12-29 00:00:00 1998-12-29 00:00:00 1998-12-29 1998-12-29 00:00:00
+1998-12-30 11:30:45 1998-12-30 11:30:45 1998-12-30 1998-12-30 11:30:45
+1998-12-31 11:30:45 1998-12-31 11:30:45 1998-12-31 1998-12-31 11:30:45
+2007-05-23 09:15:28 2007-05-23 09:15:28 2007-05-24 2007-05-24 09:15:28
+2007-05-25 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 00:00:00 2009-01-29 2009-01-29 00:00:00
+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 c1 BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY c1 DESC LIMIT 2;
+c1 c2 c3 c4
+2009-01-29 11:11:27 2009-01-29 00:00:00 2009-01-29 2009-01-29 00:00:00
+2008-01-01 00:00:00 NULL 2008-01-02 2008-01-03 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '2010-00-01 00:00:00' for column 'c1' at row 1
+Warning 1292 Incorrect datetime value: '2010-00-01 00:00:00' for column 'c1' at row 1
+SELECT * FROM t1 WHERE c2 BETWEEN '1971-01-01 00:00:01' AND '2010-10-00 00:00:00' ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2009-01-29 11:11:27 2009-01-29 00:00:00 2009-01-29 2009-01-29 00:00:00
+2007-05-25 00:00:00 2007-05-25 00:00:00 2007-05-26 2007-05-26 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '2010-10-00 00:00:00' for column 'c2' at row 1
+Warning 1292 Incorrect datetime value: '2010-10-00 00:00:00' for column 'c2' at row 1
+DROP TABLE t1;
+set time_zone= @save_time_zone;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result
new file mode 100644
index 00000000000..a2d173f5140
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result
@@ -0,0 +1,199 @@
+DROP TABLE IF EXISTS CC, C, BB;
+CREATE TABLE `CC` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`datetime_key` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES
+(10,0,'2006-07-07 07:26:28','q'),(11,5,'2002-09-23 00:00:00','m'),
+(12,7,'0000-00-00 00:00:00','j'),(13,1,'2006-06-07 00:00:00','z'),
+(14,8,'2000-09-16 12:15:34','a'),(15,2,'2007-08-05 15:47:52',''),
+(16,1,'0000-00-00 00:00:00','e'),(17,8,'2005-12-02 19:34:26','t'),
+(18,5,'0000-00-00 00:00:00','q'),(19,4,'0000-00-00 00:00:00','b'),
+(20,5,'2007-12-28 00:00:00','w'),(21,3,'2004-08-02 11:48:43','m'),
+(22,0,'0000-00-00 00:00:00','x'),(23,8,'2004-04-19 12:18:43',''),
+(24,0,'2009-04-27 00:00:00','w'),(25,4,'2006-10-20 14:52:15','x'),
+(26,0,'0000-00-00 00:00:00','e'),(27,0,'2002-03-22 11:48:37','e'),
+(28,2,'0000-00-00 00:00:00','p'),(29,0,'2001-01-04 03:55:07','x');
+CREATE TABLE `C` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`datetime_key` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES
+(1,9,'0000-00-00 00:00:00','p'),(2,0,'2002-02-09 07:38:13','v'),
+(3,8,'2001-05-03 12:08:14','t'),(4,3,'0000-00-00 00:00:00','u'),
+(5,7,'2009-07-28 03:43:30','n'),(6,0,'2009-08-04 00:00:00','l'),
+(7,1,'0000-00-00 00:00:00','h'),(8,9,'0000-00-00 00:00:00','u'),
+(9,0,'2005-08-02 17:16:54','n'),(10,9,'2002-12-21 00:00:00','j'),
+(11,0,'2005-08-15 12:37:35','k'),(12,5,'0000-00-00 00:00:00','e'),
+(13,0,'2006-03-10 00:00:00','i'),(14,8,'2005-05-16 11:02:36','u'),
+(15,8,'2008-11-02 00:00:00','n'),(16,5,'2006-03-15 00:00:00','b'),
+(17,1,'0000-00-00 00:00:00','x'),(18,7,'0000-00-00 00:00:00',''),
+(19,0,'2008-12-17 20:15:40','q'),(20,9,'0000-00-00 00:00:00','u');
+CREATE TABLE `BB` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`datetime_key` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `BB` VALUES
+(10,8,'2007-08-19 08:08:38','i'),(11,0,'2000-05-21 03:51:51','');
+SELECT DISTINCT `datetime_key`
+FROM C
+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 INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: 'i'
+Warning 1292 Truncated incorrect INTEGER value: ''
+DROP TABLE CC, C, BB;
+DROP TABLE IF EXISTS CC, C, BB;
+CREATE TABLE `CC` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+`date_key` date NOT NULL,
+`datetime_key` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `date_key` (`date_key`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES
+(10,0,8,'2007-02-14','2006-07-07 07:26:28','q','q'),
+(11,5,8,'2002-10-03','2002-09-23 00:00:00','m','m'),
+(12,7,3,'2006-12-02','0000-00-00 00:00:00','j','j'),
+(13,1,2,'2007-05-02','2006-06-07 00:00:00','z','z'),
+(14,8,2,'2001-11-18','2000-09-16 12:15:34','a','a'),
+(15,2,6,'2006-09-09','2007-08-05 15:47:52','',''),
+(16,1,8,'0000-00-00','0000-00-00 00:00:00','e','e'),
+(17,8,9,'2003-07-22','2005-12-02 19:34:26','t','t'),
+(18,5,2,'2001-12-22','0000-00-00 00:00:00','q','q'),
+(19,4,6,'0000-00-00','0000-00-00 00:00:00','b','b'),
+(20,5,5,'2006-09-02','2007-12-28 00:00:00','w','w'),
+(21,3,2,'0000-00-00','2004-08-02 11:48:43','m','m'),
+(22,0,4,'0000-00-00','0000-00-00 00:00:00','x','x'),
+(23,8,9,'2001-02-28','2004-04-19 12:18:43','',''),
+(24,0,6,'0000-00-00','2009-04-27 00:00:00','w','w'),
+(25,4,5,'2007-05-19','2006-10-20 14:52:15','x','x'),
+(26,0,0,'2005-02-15','0000-00-00 00:00:00','e','e'),
+(27,0,0,'2000-10-19','2002-03-22 11:48:37','e','e'),
+(28,2,8,'2005-07-07','0000-00-00 00:00:00','p','p'),
+(29,0,0,'2008-10-18','2001-01-04 03:55:07','x','x');
+CREATE TABLE `C` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+`date_key` date NOT NULL,
+`datetime_key` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `date_key` (`date_key`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES
+(1,9,9,'2007-12-01','0000-00-00 00:00:00','p','p'),
+(2,0,0,'0000-00-00','2002-02-09 07:38:13','v','v'),
+(3,8,6,'0000-00-00','2001-05-03 12:08:14','t','t'),
+(4,3,6,'2002-05-07','0000-00-00 00:00:00','u','u'),
+(5,7,6,'0000-00-00','2009-07-28 03:43:30','n','n'),
+(6,0,4,'0000-00-00','2009-08-04 00:00:00','l','l'),
+(7,1,7,'0000-00-00','0000-00-00 00:00:00','h','h'),
+(8,9,4,'0000-00-00','0000-00-00 00:00:00','u','u'),
+(9,0,8,'0000-00-00','2005-08-02 17:16:54','n','n'),
+(10,9,4,'2000-12-18','2002-12-21 00:00:00','j','j'),
+(11,0,7,'2005-11-13','2005-08-15 12:37:35','k','k'),
+(12,5,5,'0000-00-00','0000-00-00 00:00:00','e','e'),
+(13,0,0,'2003-11-12','2006-03-10 00:00:00','i','i'),
+(14,8,5,'2006-02-20','2005-05-16 11:02:36','u','u'),
+(15,8,7,'2005-02-12','2008-11-02 00:00:00','n','n'),
+(16,5,2,'2009-07-20','2006-03-15 00:00:00','b','b'),
+(17,1,8,'2005-02-24','0000-00-00 00:00:00','x','x'),
+(18,7,0,'0000-00-00','0000-00-00 00:00:00','',''),
+(19,0,9,'0000-00-00','2008-12-17 20:15:40','q','q'),
+(20,9,5,'0000-00-00','0000-00-00 00:00:00','u','u');
+CREATE TABLE `BB` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+`date_key` date NOT NULL,
+`datetime_key` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `date_key` (`date_key`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `BB` VALUES (10,8,5,'0000-00-00','2007-08-19
+08:08:38','i','i'),(11,0,8,'2005-08-18','2000-05-21 03:51:51','','');
+SELECT DISTINCT BIT_AND( OUTR . `datetime_key` ) AS X
+FROM C AS OUTR
+WHERE ( OUTR . `int_nokey` , OUTR . `pk` ) IN (
+SELECT DISTINCT INNR . `pk` AS X , INNR . `pk` AS Y
+FROM CC AS INNR2 LEFT JOIN BB AS INNR ON
+( INNR2 . `varchar_nokey` = INNR . `varchar_key` )
+WHERE INNR . `date_key` BETWEEN '2009-04-26' AND '2004-08-21' )
+AND OUTR . `pk` = 9
+ORDER BY OUTR . `int_key` , OUTR . `pk`;
+X
+18446744073709551615
+DROP TABLE CC, C, BB;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result
new file mode 100644
index 00000000000..45e502ca5a4
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result
@@ -0,0 +1,100 @@
+CREATE TABLE `CC` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_key` int(11) DEFAULT NULL,
+`date_nokey` date DEFAULT NULL,
+`datetime_nokey` datetime DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES (10,8,NULL,'2002-02-26 06:14:37'),(11,9,'2006-06-14','1900-01-01 00:00:00'),(12,9,'2002-09-12','2006-12-03 09:37:26'),(13,186,'2005-02-15','2008-05-26 12:27:10'),(14,NULL,NULL,'2004-12-14 16:37:30'),(15,2,'2008-11-04','2003-02-11 21:19:41'),(16,3,'2004-09-04','2009-10-18 02:27:49'),(17,0,'2006-06-05','2000-09-26 07:45:57'),(18,133,'1900-01-01',NULL),(19,1,'1900-01-01','2005-11-10 12:40:29'),(20,8,'1900-01-01','2009-04-25 00:00:00'),(21,5,'2005-01-13','2002-11-27 00:00:00'),(22,5,'2006-05-21','2004-01-26 20:32:32'),(23,8,'2003-09-08','2007-10-26 11:41:40'),(24,6,'2006-12-23','2005-10-07 00:00:00'),(25,51,'2006-10-15','2000-07-15 05:00:34'),(26,4,'2005-04-06','2000-04-03 16:33:32'),(27,7,'2008-04-07',NULL),(28,6,'2006-10-10','2001-04-25 01:26:12'),(29,4,'1900-01-01','2000-12-27 00:00:00');
+CREATE TABLE `C` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_key` int(11) DEFAULT NULL,
+`date_nokey` date DEFAULT NULL,
+`datetime_nokey` datetime DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES (1,2,NULL,'2004-10-11 18:13:16'),(2,9,'2001-09-19',NULL),(3,3,'2004-09-12','1900-01-01 00:00:00'),(4,9,NULL,'2009-07-25 00:00:00'),(5,NULL,'2002-07-19',NULL),(6,9,'2002-12-16','2008-07-27 00:00:00'),(7,3,'2006-02-08','2002-11-13 16:37:31'),(8,8,'2006-08-28','1900-01-01 00:00:00'),(9,8,'2001-04-14','2003-12-10 00:00:00'),(10,53,'2000-01-05','2001-12-21 22:38:22'),(11,0,'2003-12-06','2008-12-13 23:16:44'),(12,5,'1900-01-01','2005-08-15 12:39:41'),(13,166,'2002-11-27',NULL),(14,3,NULL,'2006-09-11 12:06:14'),(15,0,'2003-05-27','2007-12-15 12:39:34'),(16,1,'2005-05-03','2005-08-09 00:00:00'),(17,9,'2001-04-18','2001-09-02 22:50:02'),(18,5,'2005-12-27','2005-12-16 22:58:11'),(19,6,'2004-08-20','2007-04-19 00:19:53'),(20,2,'1900-01-01','1900-01-01 00:00:00');
+SELECT `pk`
+FROM C OUTR
+WHERE `pk` IN (
+SELECT `int_key`
+FROM CC
+WHERE `date_nokey` < `datetime_nokey` XOR OUTR .`date_nokey` ) ;
+pk
+9
+2
+5
+6
+SELECT `pk`
+FROM C
+WHERE `pk` IN (
+SELECT `int_key`
+FROM CC
+WHERE `date_nokey` < `datetime_nokey` XOR '2009-11-25' ) ;
+pk
+2
+4
+5
+6
+9
+Warnings:
+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'
+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` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) DEFAULT NULL,
+`int_key` int(11) DEFAULT NULL,
+`date_nokey` date DEFAULT NULL,
+`datetime_key` datetime DEFAULT NULL,
+`datetime_nokey` datetime DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES (10,7,8,NULL,'2002-02-26 06:14:37','2002-02-26 06:14:37'),(11,1,9,'2006-06-14','1900-01-01 00:00:00','1900-01-01 00:00:00'),(12,5,9,'2002-09-12','2006-12-03 09:37:26','2006-12-03 09:37:26'),(13,3,186,'2005-02-15','2008-05-26 12:27:10','2008-05-26 12:27:10'),(14,6,NULL,NULL,'2004-12-14 16:37:30','2004-12-14 16:37:30'),(15,92,2,'2008-11-04','2003-02-11 21:19:41','2003-02-11 21:19:41'),(16,7,3,'2004-09-04','2009-10-18 02:27:49','2009-10-18 02:27:49'),(17,NULL,0,'2006-06-05','2000-09-26 07:45:57','2000-09-26 07:45:57'),(18,3,133,'1900-01-01',NULL,NULL),(19,5,1,'1900-01-01','2005-11-10 12:40:29','2005-11-10 12:40:29'),(20,1,8,'1900-01-01','2009-04-25 00:00:00','2009-04-25 00:00:00'),(21,2,5,'2005-01-13','2002-11-27 00:00:00','2002-11-27 00:00:00'),(22,NULL,5,'2006-05-21','2004-01-26 20:32:32','2004-01-26 20:32:32'),(23,1,8,'2003-09-08','2007-10-26 11:41:40','2007-10-26 11:41:40'),(24,0,6,'2006-12-23','2005-10-07 00:00:00','2005-10-07 00:00:00'),(25,210,51,'2006-10-15','2000-07-15 05:00:34','2000-07-15 05:00:34'),(26,8,4,'2005-04-06','2000-04-03 16:33:32','2000-04-03 16:33:32'),(27,7,7,'2008-04-07',NULL,NULL),(28,5,6,'2006-10-10','2001-04-25 01:26:12','2001-04-25 01:26:12'),(29,NULL,4,'1900-01-01','2000-12-27 00:00:00','2000-12-27 00:00:00');
+CREATE TABLE `C` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) DEFAULT NULL,
+`int_key` int(11) DEFAULT NULL,
+`date_nokey` date DEFAULT NULL,
+`datetime_key` datetime DEFAULT NULL,
+`datetime_nokey` datetime DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `int_key` (`int_key`),
+KEY `datetime_key` (`datetime_key`),
+KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES (1,NULL,2,NULL,'2004-10-11 18:13:16','2004-10-11 18:13:16'),(2,7,9,'2001-09-19',NULL,NULL),(3,9,3,'2004-09-12','1900-01-01 00:00:00','1900-01-01 00:00:00'),(4,7,9,NULL,'2009-07-25 00:00:00','2009-07-25 00:00:00'),(5,4,NULL,'2002-07-19',NULL,NULL),(6,2,9,'2002-12-16','2008-07-27 00:00:00','2008-07-27 00:00:00'),(7,6,3,'2006-02-08','2002-11-13 16:37:31','2002-11-13 16:37:31'),(8,8,8,'2006-08-28','1900-01-01 00:00:00','1900-01-01 00:00:00'),(9,NULL,8,'2001-04-14','2003-12-10 00:00:00','2003-12-10 00:00:00'),(10,5,53,'2000-01-05','2001-12-21 22:38:22','2001-12-21 22:38:22'),(11,NULL,0,'2003-12-06','2008-12-13 23:16:44','2008-12-13 23:16:44'),(12,6,5,'1900-01-01','2005-08-15 12:39:41','2005-08-15 12:39:41'),(13,188,166,'2002-11-27',NULL,NULL),(14,2,3,NULL,'2006-09-11 12:06:14','2006-09-11 12:06:14'),(15,1,0,'2003-05-27','2007-12-15 12:39:34','2007-12-15 12:39:34'),(16,1,1,'2005-05-03','2005-08-09 00:00:00','2005-08-09 00:00:00'),(17,0,9,'2001-04-18','2001-09-02 22:50:02','2001-09-02 22:50:02'),(18,9,5,'2005-12-27','2005-12-16 22:58:11','2005-12-16 22:58:11'),(19,NULL,6,'2004-08-20','2007-04-19 00:19:53','2007-04-19 00:19:53'),(20,4,2,'1900-01-01','1900-01-01 00:00:00','1900-01-01 00:00:00');
+SELECT OUTR . `pk` AS X
+FROM C AS OUTR
+WHERE OUTR . `pk` IN (
+SELECT INNR . `int_key` AS Y
+FROM CC AS INNR
+WHERE INNR . `date_nokey` < INNR . `datetime_nokey` XOR OUTR . `date_nokey` BETWEEN '2004-07-10' AND '2009-11-25'
+ORDER BY INNR . `int_nokey` ) AND ( OUTR . `datetime_key` BETWEEN '2000-05-25' AND '2004-08-07' OR OUTR . `datetime_nokey` = '2007-10-24' )
+ORDER BY OUTR . `int_key` , OUTR . `pk`;
+X
+9
+DROP TABLE CC;
+DROP TABLE C;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug49129.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug49129.result
new file mode 100644
index 00000000000..2612e4d0bf2
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug49129.result
@@ -0,0 +1,39 @@
+SET SESSION optimizer_switch = 'firstmatch=off,index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,loosescan=on,materialization=on,semijoin=on';
+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;
+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;
+UPDATE t2 SET b=11 WHERE a=3;
+
+# This result is wrong, but will be fixed by Bug#46556
+SELECT * FROM t0 WHERE t0.a IN
+(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+a
+0
+1
+2
+3
+SET join_cache_level = 6;
+
+# This result is even more wrong ;-)
+SELECT * FROM t0 WHERE t0.a IN
+(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+a
+0
+1
+2
+3
+
+# This result is correct
+SET SESSION optimizer_switch = 'semijoin=off';
+SELECT * FROM t0 WHERE t0.a IN
+(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+a
+0
+1
+2
+3
+DROP TABLE t0, t1, t2;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug36981.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug36981.test
new file mode 100644
index 00000000000..586602c7ae8
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug36981.test
@@ -0,0 +1,14 @@
+# test for BUG#36981 "innodb crash when selecting for update"
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+# crash requires this
+set session debug="+d,optimizer_innodb_icp";
+
+create table `t1` (`c1` char(1) default null,`c2` char(10) default null,
+key (`c1`))
+engine=innodb default charset=latin1;
+insert into `t1` values ('3',null);
+select * from `t1` where `c1`='3' for update;
+drop table `t1`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug40992.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug40992.test
new file mode 100644
index 00000000000..36fe7c4a60f
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug40992.test
@@ -0,0 +1,21 @@
+--echo #
+--echo # Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
+--echo #
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+# Crash requires that we enable Index Condition Pushdown in InnoDB
+set session debug="+d,optimizer_innodb_icp";
+
+CREATE TABLE t (
+ dummy INT PRIMARY KEY,
+ a INT UNIQUE,
+ b int
+) ENGINE=InnoDB;
+
+INSERT INTO t VALUES (1,1,1),(3,3,3),(5,5,5);
+
+SELECT * FROM t WHERE a > 2 FOR UPDATE;
+
+DROP TABLE t;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41029-master.opt b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41029-master.opt
new file mode 100644
index 00000000000..bb3f82d4dd6
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41029-master.opt
@@ -0,0 +1 @@
+--loose-innodb_lock_wait_timeout=3
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41029.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41029.test
new file mode 100644
index 00000000000..ff3dd4964af
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41029.test
@@ -0,0 +1,44 @@
+# test for BUG#41029:
+# "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+select @default_binlog_format:=@@global.binlog_format;
+set global binlog_format=row;
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+
+# bug requires this
+set session debug="+d,optimizer_innodb_ds_mrr";
+
+set autocommit=0;
+use test;
+drop table if exists t1;
+create table t1 (dummy int primary key, a int unique, b int) engine=innodb;
+insert into t1 values(1,1,1),(3,3,3),(5,5,5);
+commit;
+set session transaction isolation level repeatable read;
+select @@tx_isolation;
+start transaction;
+select * from t1 where a > 2 for update;
+
+connection con2;
+
+use test;
+set autocommit=0;
+start transaction;
+select 1;
+--error ER_LOCK_WAIT_TIMEOUT
+insert into t1 values(2,2,2);
+rollback;
+
+connection con1;
+rollback;
+
+drop table t1;
+connection default;
+set global binlog_format=@default_binlog_format;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1-innodb.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1-innodb.test
new file mode 100644
index 00000000000..deb90136326
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1-innodb.test
@@ -0,0 +1,487 @@
+set optimizer_use_mrr='disable';
+--disable_warnings
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+--enable_warnings
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1.test
new file mode 100644
index 00000000000..deb90136326
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1.test
@@ -0,0 +1,487 @@
+set optimizer_use_mrr='disable';
+--disable_warnings
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+--enable_warnings
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE d1.t1, d2.t2 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE d1.t1.*, d2.t2.*, d3.t3 FROM d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2-innodb.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2-innodb.test
new file mode 100644
index 00000000000..2590ed7b0e3
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2-innodb.test
@@ -0,0 +1,486 @@
+--disable_warnings
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+--enable_warnings
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2.test
new file mode 100644
index 00000000000..2590ed7b0e3
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra2.test
@@ -0,0 +1,486 @@
+--disable_warnings
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+--enable_warnings
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE DATABASE d3;
+CREATE TABLE d1.t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d2.t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE d3.t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO d1.t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO d2.t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO d3.t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM d1.t1, d2.t2 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM d1.t1, d2.t2, d3.t3 USING d1.t1, d2.t2, d3.t3 WHERE d1.t1.c1=d2.t2.c2 AND d2.t2.c1=d3.t3.c2;
+SELECT * FROM d1.t1 ORDER BY c1;
+SELECT * FROM d2.t2 ORDER BY c1;
+SELECT * FROM d3.t3 ORDER BY c1;
+DROP DATABASE d1;
+DROP DATABASE d2;
+DROP DATABASE d3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3-innodb.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3-innodb.test
new file mode 100644
index 00000000000..70e727a4c43
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3-innodb.test
@@ -0,0 +1,363 @@
+--disable_warnings
+--enable_warnings
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3.test
new file mode 100644
index 00000000000..70e727a4c43
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra3.test
@@ -0,0 +1,363 @@
+--disable_warnings
+--enable_warnings
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE t1, t2 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE t1.*, t2.*, t3 FROM t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4-innodb.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4-innodb.test
new file mode 100644
index 00000000000..ce0be3c7b12
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4-innodb.test
@@ -0,0 +1,363 @@
+--disable_warnings
+--enable_warnings
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4.test
new file mode 100644
index 00000000000..ce0be3c7b12
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra4.test
@@ -0,0 +1,363 @@
+--disable_warnings
+--enable_warnings
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 TINYINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 INTEGER NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t2 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+CREATE TABLE t3 (c1 BIGINT NOT NULL PRIMARY KEY, c2 INTEGER, KEY(c2));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(4,4),(5,5);
+INSERT INTO t2 VALUES(11,1),(12,1),(13,1),(14,2),(15,6);
+INSERT INTO t3 VALUES(21,11),(22,11),(23,13),(24,14),(25,15);
+DELETE QUICK IGNORE FROM t1, t2 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DELETE QUICK IGNORE FROM t1, t2, t3 USING t1, t2, t3 WHERE t1.c1=t2.c2 AND t2.c1=t3.c2;
+SELECT * FROM t1 ORDER BY c1;
+SELECT * FROM t2 ORDER BY c1;
+SELECT * FROM t3 ORDER BY c1;
+DROP TABLE t1,t2,t3;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996.test
new file mode 100644
index 00000000000..b8040b9714a
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996.test
@@ -0,0 +1,14 @@
+# Test for BUG#41996 "multi-table delete crashes server (InnoDB
+# table)"
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+# crash requires this
+set session debug="+d,optimizer_innodb_icp";
+
+drop table if exists `t1`;
+create table `t1` (`c` bigint, key(`c`),`a` int)engine=innodb;
+insert into `t1` values(2,2);
+delete `t1` from `t1` `a`, `t1` where `a`.`a`=`t1`.`c` ;
+drop table `t1`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug42991.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug42991.test
new file mode 100644
index 00000000000..d3eb1e726a2
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug42991.test
@@ -0,0 +1,248 @@
+--source include/have_debug.inc
+# Test for BUG#42991 "invalid memory access and/or crash when using
+# index condition pushdown + InnoDB"
+# Note that you need to run with --valgrind to see the warnings
+# about invalid memory accesses.
+
+--source include/have_innodb.inc
+
+# Valgrind errors happen only with this:
+set session debug="+d,optimizer_innodb_icp";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+
+DROP TABLE IF EXISTS `table5`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+CREATE TABLE `table5` (
+ `col0` mediumtext,
+ `col1` varchar(90) DEFAULT NULL,
+ `col2` tinytext,
+ `col3` time DEFAULT NULL,
+ `col4` tinyint(1) DEFAULT NULL,
+ `col5` tinytext,
+ `col6` tinyint(1) DEFAULT NULL,
+ `col7` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `col8` tinyblob,
+ `col9` tinyint(4) DEFAULT NULL,
+ `col10` year(4) DEFAULT NULL,
+ `col11` set('test1','test2','test3') DEFAULT NULL,
+ `col12` text,
+ `col13` char(248) DEFAULT NULL,
+ `col14` bigint(20) DEFAULT NULL,
+ `col15` text,
+ `col16` tinyint(4) DEFAULT NULL,
+ `col17` decimal(10,0) DEFAULT NULL,
+ `col18` set('test1','test2','test3') DEFAULT NULL,
+ `col19` varchar(255) DEFAULT NULL,
+ `col20` float DEFAULT NULL,
+ `col21` int(11) DEFAULT NULL,
+ `col22` text,
+ `col23` tinyint(1) DEFAULT NULL,
+ `col24` decimal(10,0) NOT NULL DEFAULT '0',
+ `col25` double DEFAULT NULL,
+ `col26` float DEFAULT NULL,
+ `col27` tinyblob,
+ `col28` decimal(10,0) DEFAULT NULL,
+ `col29` mediumblob,
+ `col30` date DEFAULT NULL,
+ `col31` longtext,
+ `col32` date DEFAULT NULL,
+ `col33` float DEFAULT NULL,
+ `col34` bigint(20) DEFAULT NULL,
+ `col35` tinytext,
+ `col36` mediumtext,
+ `col37` time DEFAULT NULL,
+ `col38` int(11) DEFAULT NULL,
+ `col39` tinyint(4) DEFAULT NULL,
+ `col40` set('test1','test2','test3') DEFAULT NULL,
+ `col41` char(130) DEFAULT NULL,
+ `col42` smallint(6) DEFAULT NULL,
+ `col43` int(11) DEFAULT NULL,
+ `col44` mediumtext,
+ `col45` varchar(126) DEFAULT NULL,
+ `col46` int(11) DEFAULT NULL,
+ `col47` double DEFAULT NULL,
+ `col48` bigint(20) DEFAULT NULL,
+ `col49` mediumtext,
+ `col50` tinyblob,
+ `col51` mediumint(9) DEFAULT NULL,
+ `col52` text,
+ `col53` varchar(208) DEFAULT NULL,
+ `col54` varchar(207) DEFAULT NULL,
+ `col55` decimal(10,0) DEFAULT NULL,
+ `col56` datetime DEFAULT NULL,
+ `col57` enum('test1','test2','test3') DEFAULT NULL,
+ `col58` decimal(10,0) DEFAULT NULL,
+ `col59` tinyblob,
+ `col60` varchar(73) DEFAULT NULL,
+ `col61` mediumtext,
+ `col62` tinyblob,
+ `col63` datetime DEFAULT NULL,
+ `col64` decimal(10,0) DEFAULT NULL,
+ `col65` mediumint(9) DEFAULT NULL,
+ `col66` datetime DEFAULT NULL,
+ `col67` decimal(10,0) DEFAULT NULL,
+ `col68` tinyint(4) DEFAULT NULL,
+ `col69` varchar(58) DEFAULT NULL,
+ `col70` decimal(10,0) DEFAULT NULL,
+ `col71` mediumtext,
+ `col72` date DEFAULT NULL,
+ `col73` time DEFAULT NULL,
+ `col74` double DEFAULT NULL,
+ `col75` decimal(10,0) DEFAULT NULL,
+ `col76` mediumblob,
+ `col77` double DEFAULT NULL,
+ `col78` year(4) DEFAULT NULL,
+ `col79` year(4) DEFAULT NULL,
+ `col80` varchar(255) DEFAULT NULL,
+ `col81` blob,
+ `col82` bigint(20) DEFAULT NULL,
+ `col83` enum('test1','test2','test3') DEFAULT NULL,
+ `col84` decimal(10,0) DEFAULT NULL,
+ `col85` set('test1','test2','test3') DEFAULT NULL,
+ `col86` mediumtext,
+ `col87` varchar(255) DEFAULT NULL,
+ `col88` time DEFAULT NULL,
+ `col89` enum('test1','test2','test3') DEFAULT NULL,
+ `col90` decimal(10,0) DEFAULT NULL,
+ `col91` float DEFAULT NULL,
+ `col92` datetime DEFAULT NULL,
+ `col93` tinytext,
+ `col94` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `col95` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `col96` text,
+ `col97` double DEFAULT NULL,
+ `col98` varchar(198) DEFAULT NULL,
+ `col99` time DEFAULT NULL,
+ `col100` tinyint(4) DEFAULT NULL,
+ `col101` bigint(20) DEFAULT NULL,
+ `col102` varchar(255) DEFAULT NULL,
+ `col103` varchar(255) DEFAULT NULL,
+ `col104` mediumint(9) DEFAULT NULL,
+ `col105` mediumtext,
+ `col106` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `col107` smallint(6) DEFAULT NULL,
+ `col108` decimal(10,0) DEFAULT NULL,
+ `col109` decimal(10,0) DEFAULT NULL,
+ `col110` float DEFAULT NULL,
+ `col111` decimal(10,0) DEFAULT NULL,
+ `col112` double DEFAULT NULL,
+ `col113` tinytext,
+ `col114` float DEFAULT NULL,
+ `col115` varchar(7) DEFAULT NULL,
+ `col116` longtext,
+ `col117` date DEFAULT NULL,
+ `col118` bigint(20) DEFAULT NULL,
+ `col119` text,
+ `col120` bigint(20) DEFAULT NULL,
+ `col121` blob,
+ `col122` char(110) DEFAULT NULL,
+ `col123` decimal(10,0) DEFAULT NULL,
+ `col124` mediumblob,
+ `col125` decimal(10,0) DEFAULT NULL,
+ `col126` decimal(10,0) DEFAULT NULL,
+ `col127` tinyint(1) DEFAULT NULL,
+ `col128` time DEFAULT NULL,
+ `col129` tinyblob,
+ `col130` tinyblob,
+ `col131` date DEFAULT NULL,
+ `col132` int(11) DEFAULT NULL,
+ `col133` varchar(123) DEFAULT NULL,
+ `col134` char(238) DEFAULT NULL,
+ `col135` varchar(225) DEFAULT NULL,
+ `col136` longtext,
+ `col137` varchar(255) DEFAULT NULL,
+ `col138` double DEFAULT NULL,
+ `col139` tinyblob,
+ `col140` datetime DEFAULT NULL,
+ `col141` tinytext,
+ `col142` varchar(255) DEFAULT NULL,
+ `col143` bigint(20) DEFAULT NULL,
+ `col144` varchar(236) DEFAULT NULL,
+ `col145` text,
+ `col146` year(4) DEFAULT NULL,
+ `col147` decimal(10,0) DEFAULT NULL,
+ `col148` text,
+ `col149` mediumblob,
+ `col150` tinyint(4) DEFAULT NULL,
+ `col151` tinyint(1) DEFAULT NULL,
+ `col152` varchar(72) DEFAULT NULL,
+ `col153` int(11) DEFAULT NULL,
+ `col154` varchar(165) DEFAULT NULL,
+ `col155` tinyint(4) DEFAULT NULL,
+ `col156` mediumtext,
+ `col157` double DEFAULT NULL,
+ `col158` time DEFAULT NULL,
+ `col159` mediumblob,
+ `col160` varchar(255) DEFAULT NULL,
+ `col161` datetime DEFAULT NULL,
+ `col162` double DEFAULT NULL,
+ `col163` blob,
+ `col164` enum('test1','test2','test3') DEFAULT NULL,
+ `col165` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `col166` date DEFAULT NULL,
+ `col167` tinyblob,
+ `col168` tinyblob,
+ `col169` varchar(255) DEFAULT NULL,
+ `col170` datetime DEFAULT NULL,
+ `col171` bigint(20) DEFAULT NULL,
+ `col172` varchar(30) DEFAULT NULL,
+ `col173` longtext,
+ `col174` time DEFAULT NULL,
+ `col175` float DEFAULT NULL,
+ PRIMARY KEY (`col24`),
+ KEY `idx0` (`col16`,`col156`(139),`col97`,`col120`),
+ KEY `idx1` (`col24`,`col0`(108)),
+ KEY `idx2` (`col117`,`col173`(34),`col132`,`col82`),
+ KEY `idx3` (`col2`(86)),
+ KEY `idx4` (`col2`(43)),
+ KEY `idx5` (`col83`,`col35`(87),`col111`),
+ KEY `idx6` (`col6`,`col134`,`col92`),
+ KEY `idx7` (`col56`),
+ KEY `idx8` (`col30`,`col53`,`col129`(66)),
+ KEY `idx9` (`col53`,`col113`(211),`col32`,`col15`(75)),
+ KEY `idx10` (`col34`),
+ KEY `idx11` (`col126`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
+
+
+LOCK TABLES `table5` WRITE;
+/*!40000 ALTER TABLE `table5` DISABLE KEYS */;
+INSERT INTO `table5` VALUES ('referenda','hermaphroditism','superable','00:00:00',-128,NULL,-128,'0000-00-00 00:00:00',NULL,-128,1901,NULL,'blandly',NULL,6541,'unsuspectingly',NULL,'7250','',NULL,-31358,26248,'Kilmarnock\'s',127,'-27305',28987,NULL,NULL,'-30388','utilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitariansutilitarians','0000-00-00','Agincourt','0000-00-00',-28063,27242,'readies',NULL,'00:00:00',NULL,-128,'',NULL,NULL,18719,NULL,NULL,14038,17275,NULL,'gait\'s','honeymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'shoneymoon\'sho',8860,NULL,'demigod','outpulling',NULL,'1904-01-17 09:51:06','test1','-18008','grotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'sgrotesqueness\'s','Oakleil\'s','Shostakovich','indiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscretionsindiscre','2076-10-05 02:05:43','29914',-18885,'2088-05-25 13:36:33','25',-128,'Bob','-14559','ammeter','0000-00-00','00:00:00',-29756,NULL,'digressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigressiondigression',-23894,1963,1915,'SadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadyeSadye',NULL,NULL,'','17512','','anaphylaxis\'s','chiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schiseler\'schise','50:11:25','test1','-13685',-18328,'2020-01-19 22:04:54',NULL,'1988-05-10 10:30:56','0000-00-00 00:00:00','Birdie\'s',-27746,NULL,'179:19:25',-128,24141,'radiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparentradiotransparen','ingroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'singroup\'sing',18950,'Beaulieu','0000-00-00 00:00:00',-23421,'-2865',NULL,NULL,NULL,NULL,'vandalizes',-24683,'interop','Apis\'s','0000-00-00',19745,'Volgograd\'s',-15194,NULL,'Binni','4540','phylumphylumphylumphylum','-25781',NULL,-128,'406:37:03','posthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthasteposthastepos','manneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristmanneristman','0000-00-00',19774,'shariah',NULL,'aquarelle','homographic',NULL,-18959,'thoroughfarethoroughfarethoroughfarethoroughfarethoroughfarethoroughfare','2000-09-05 03:33:50','Baptlsta','Witt\'sWitt\'sWitt\'sWitt\'sWitt\'sWitt\'sWitt\'sWitt\'s',4727,NULL,'posting',2119,'32416',NULL,'charredcharredcharredcharredcharredcharredcharredcharredcharredcharred',-128,NULL,'Rollin\'s',NULL,NULL,127,'waviness\'s',11164,'424:28:18','FaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucherFaucher','stalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'sstalactite\'s','1901-01-29 13:48:34',-31988,'Dyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'sDyan\'s','','2022-01-01 21:14:30','0000-00-00','conventionalistconventionalistconventionalistconventionalistconventionalistconventionalistconventionalistconventionalist','mirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnessesmirthlessnesses','tessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stessellation\'stes','2028-05-21 04:56:16',NULL,'Hasid','Hardecanute','00:00:00',-3782);
+INSERT INTO `table5` VALUES ('hemoglobin\'s','Toffey\'s','Juvenal','00:00:00',-128,'harmonicon',-128,'2004-02-13 09:45:46',NULL,NULL,1911,'','Tananarive\'s',NULL,30666,'spiniferous',127,'30675','','Frederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFrederick\'sFr',30388,4769,'Erymanthus\'s',127,'-20972',NULL,-17111,'explosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosivenessexplosiveness','-28154','magnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'smagnitude\'s','0000-00-00','removes','0000-00-00',16859,NULL,NULL,'Moishe\'s','00:00:00',NULL,NULL,NULL,'hyperform\'s',30540,-26603,'soporific',NULL,NULL,19264,-14618,NULL,'zootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszootechnicszo',5654,'intermezzi','Atkins\'s','hieroglyphically','15885','2068-10-19 12:22:30','','4972','apatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapatosaurapa','severeness','pleaders',NULL,'2070-09-15 17:21:46','15245',-18313,'1934-01-01 01:20:15','-3488',127,'Delawarian','14952','foregathers','0000-00-00','00:00:00',-27837,'7143','madhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'smadhouse\'s',-17163,1951,2054,'raffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraffiaraf','REMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMsREMs',3607,'','-17633','',NULL,NULL,'806:59:31','test1','-29600',20301,'1985-10-09 17:57:25',NULL,'0000-00-00 00:00:00','0000-00-00 00:00:00','Perseid',-32117,'constructer\'s','612:19:03',127,NULL,'overdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingoverdressingove','Carlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCarlstrom\'sCa',24868,'preamble','0000-00-00 00:00:00',-7582,'-865','-14488',6884,'-24713',NULL,'topknot\'s',18469,NULL,'histrionism\'s','0000-00-00',31715,'Dag',14543,'wooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'swooziness\'s','tightest',NULL,'aquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'saquiculture\'s','15603',NULL,-128,'640:34:17','acetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumacetabulumaceta','torridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridlytorridl','9323-05-13',-28292,'Barnaul\'s',NULL,'slanginesses','supernova',NULL,20804,NULL,'2020-10-05 12:00:38','rive',NULL,-31498,'considerateness\'s','nevus\'s',1901,'-12956','fashioner\'s','unfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'sunfitness\'s',-128,127,'nephralgia\'s',13881,'sciatically',NULL,'Tuesday',21227,'00:00:00','halocarbons','duvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduvetynduv','2075-01-21 10:49:44',-19735,'snubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubssnubs','test1','0000-00-00 00:00:00','0000-00-00','kiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkiblahkib',NULL,'connoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseursconnoisseurscon','1953-01-23 17:36:00',NULL,'Principal',NULL,'316:28:48',NULL);
+INSERT INTO `table5` VALUES (NULL,'Annmarie','intangibleness\'s','00:00:00',-128,'transmogrify',127,'0000-00-00 00:00:00',NULL,127,2093,'','enamored','refired',-21296,'neglectful',127,'-9992','',NULL,NULL,3583,'Lockheed\'s',127,'-15717',-29743,-16280,'embouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembouchureembou','-24875',NULL,'0000-00-00',NULL,'0000-00-00',30124,20356,'drinkable','obscenity','00:00:00',NULL,127,'',NULL,-16664,NULL,'unmoor','Vaughan\'s',30457,-16509,-10049,'squeamishness','encirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencirclingencir',-16460,'abatement\'s',NULL,'expatriate','-28670','1925-05-15 11:44:20','','-3762','DelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDelwynDel','Skerl\'s','unmatched',NULL,'1980-01-11 16:02:04','25917',18187,'2001-07-26 13:48:08','-28706',127,'gimme','8807',NULL,'0000-00-00','00:00:00',7666,'21762','drawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacksdrawbacks',16131,2031,2077,'subjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysubjectivitysub','Argenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'sArgenteuil\'s',NULL,'','-17090','','fobs','humiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliatinglyhumiliat','221:02:40','','-1107',4624,'1926-05-11 03:35:52',NULL,'2037-05-13 05:02:44','0000-00-00 00:00:00','Heddie\'s',-6554,NULL,'00:00:00',127,NULL,'lxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlxlx','RawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawleyRawley',6613,'Beaufort','0000-00-00 00:00:00',12214,NULL,'25469',-26474,'12062',NULL,'physiographer',26382,'cosmogo','deportment\'s','0000-00-00',17492,'propretor\'s',NULL,'zingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzingzing','Suzetta','25513','tearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkerstearjerkers','21613',NULL,-128,'108:58:18','sporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallysporadicallyspo','Monera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'sMonera\'','0000-00-00',18776,'diffractometer',NULL,'crawls','Inglebert','unguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableunguessableun',18112,'melanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanismmelanis','1940-05-18 13:21:00','artlessly','blotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblotsblots',6476,NULL,'Bartlett',2143,NULL,'thaumaturge\'s','Hazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'sHazelton\'s',127,127,'Winthorpe',-29765,'idiocrasy\'s',NULL,'sandcastles',-9852,'281:41:52','Volny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'sVolny\'s','protagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagonist\'sprotagon','2076-01-04 15:01:57',NULL,'auscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultationsauscultations','','0000-00-00 00:00:00','0000-00-00','limenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimenlimen','accommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatinglyaccommodatingly',NULL,'2018-01-01 05:48:54',17404,NULL,NULL,'195:36:50',24658);
+INSERT INTO `table5` VALUES ('caddishly',NULL,'Kotah','00:00:00',-128,'tailoring',127,'0000-00-00 00:00:00','trustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustiestrustie',-128,1967,NULL,NULL,'parallelisms',NULL,NULL,127,NULL,'',NULL,NULL,-513,NULL,NULL,'-14518',NULL,-22393,'AngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAngeliAng','32257','regalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregalingregaling','0000-00-00','newspaperwoman','0000-00-00',24845,-17741,'impassiveness','Antillean','00:00:00',-13615,-128,'','gantries',-27983,-6070,'Benetton','aridest',NULL,21574,-25634,'McWilliams\'s','burrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowedburrowe',18947,NULL,NULL,'surrealistic',NULL,'1954-07-07 08:58:49','test1','-11714','ExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExExEx','administrants','Oxycontin','interpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterpersonalinterper','1914-05-28 05:15:03','3942',NULL,'2046-09-07 18:16:36','3220',127,'arising','18472','anacolutha','0000-00-00','613:15:45',NULL,'-23969',NULL,18979,2031,1975,'AlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcestisAlcesti','septicitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticitiessepticities',-25058,'',NULL,'','Kulturkampf','pollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpollutantpol','00:00:00','','12283',2881,'1926-12-10 09:24:42','Darken\'s','2034-12-21 15:59:00','0000-00-00 00:00:00',NULL,NULL,NULL,'305:05:06',127,NULL,'feudalityfeudality','Merrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMerrili\'sMer',-25733,'borak','0000-00-00 00:00:00',-11465,'877',NULL,-1029,'5107',NULL,'Balaton\'s',NULL,'Martian','miserliness','0000-00-00',14689,'catchment',18457,'billet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'sbillet\'s','humerus\'s','24741',NULL,NULL,'-19233',-128,'00:00:00','fashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfashfas','judiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjudiciaryjud','0000-00-00',15972,'Letrice\'s','hydrographer',NULL,'Federica','evidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevidentlyevi',4115,'pshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspshawspsh','1924-10-15 16:31:18','Hamlet','trowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'strowel\'',-3485,'galvanized',NULL,1924,'-22877','unfired','inchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'sinchworm\'s',-128,-128,'VHF',-5304,NULL,127,'glossator',16348,'213:10:59','',NULL,'1946-01-11 17:25:16',262,'DoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDoutyDouty','test1','0000-00-00 00:00:00','0000-00-00',NULL,'feasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasiblefeasibl','contortionisticcontortionisticcontortionisticcontortionisticcontortionisticcontortionisticcontortionistic','2027-06-09 07:56:16',6909,'tessitura','indefensible','00:00:00',-6628);
+INSERT INTO `table5` VALUES ('bassoonist\'s',NULL,'refastens','114:27:50',127,'unrestricted',127,'2032-01-13 11:11:22','abstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'sabstainer\'s',NULL,1955,'','Hodosh','allocates',-5067,'Cenac\'s',-128,'31546',NULL,'impassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassabilityimpassab',-30347,292,'Sandi\'s',NULL,'-12402',8206,NULL,'encircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircleencircl','6346','ArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentiniansArgentinians','0000-00-00','Riehl\'s','0000-00-00',NULL,5580,'planets',NULL,'58:35:07',317,127,'','gender',-19514,7112,'Pissaro','relevantly',28777,-21818,-17111,'shoddiness\'s',NULL,NULL,'flee','Boatwright\'s','restrict','12537','2096-04-25 08:45:21','test1','-4613','quagga','masterstroke\'s','overcheck\'s',NULL,'1981-10-14 18:30:02','21097',-26481,'2065-07-11 02:13:44',NULL,NULL,'bathroom','-29833','gracelessness\'s','0000-00-00','09:44:40',-7368,NULL,'applecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'sapplecart\'s',-21077,2015,2039,'cascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scascara\'scas','nervingnervingnervingnervingnervingnervingnervingnervingnervingnerving',22043,'','5740','','mustached','actin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'sactin\'s','00:00:00','test1','13871',-22276,'1956-01-05 15:08:47','slimline','0000-00-00 00:00:00','0000-00-00 00:00:00','royally',NULL,'mako','51:54:53',NULL,NULL,'deliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'sdeliquescence\'s','DOADOADOADOADOADOADOADOADOADOADOADOADOA',-16244,'Fayette\'s','2020-06-21 05:34:18',-24353,'24097','-28819',12278,'-2365',21322,'stumps',-61,NULL,'subpoena\'s','0000-00-00',31242,'knicker',23567,NULL,'Cathar','29557','thallusthallusthallusthallusthallusthallusthallusthallusthallusthallus','26114',NULL,-128,'00:00:00','salmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsalmonoidsal','shiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshiveshive','0000-00-00',-3152,'syndesis','misbrands','Smiga','stagnation\'s','nonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricnonelectricno',NULL,NULL,'1988-09-11 14:33:03',NULL,'provokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglyprovokinglypr',25510,'thunderpeal\'s','hierology',1932,'7729','Fahrenheit','metathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'smetathesis\'s',NULL,-128,'sinfonia\'s',-6293,'proactive',127,NULL,-24751,'00:00:00','woodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopperwoodchopper','Constantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'sConstantinople\'','1997-01-01 22:40:48',NULL,'MatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlickMatlick','test1','2000-12-17 11:19:08','0000-00-00',NULL,'cosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmicalcosmica','Loesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesceke\'sLoesc','2078-07-25 04:56:08',10472,NULL,NULL,'345:12:02',-13120);
+INSERT INTO `table5` VALUES ('segmentation\'s','shapelessness\'s','coagulators','127:46:24',-128,NULL,127,'0000-00-00 00:00:00','seekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingseekingsee',NULL,2085,'','indent','flyblown',NULL,'Alegre',-128,'-27917','','DesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDesiraeDes',2473,NULL,'screwball\'s',NULL,'-4861',-7088,-30734,'tambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintambourintam',NULL,NULL,'0000-00-00','Dorcia','0000-00-00',-25745,-1237,'Shoifet\'s','sarsaparillas','21:11:41',31612,-128,'','subway\'s',-5032,-30369,'preventives','lyre',7995,21283,13197,'chippies','rubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubiginousrubig',19050,'orch','semiliterates','Gerome',NULL,'2058-12-26 21:29:19','',NULL,'dyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdyad\'sdya','Dukas\'s','Christiania','polyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvalenciespolyvale','1920-05-23 14:07:00','672',NULL,'1956-06-27 12:15:00','-22658',NULL,'holograph\'s',NULL,'gutsy','0000-00-00','00:00:00',-9558,'1148','fainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfainsfains',NULL,2023,2132,'Balmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBalmung\'sBal','overdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdooverdo',-24707,'test1','-13970','','tensility','BuddieBuddieBuddieBuddieBuddieBuddieBuddieBuddieBuddieBuddie','00:00:00','','580',25115,'2000-07-01 09:01:36','apprentice','1992-01-01 08:55:38','0000-00-00 00:00:00','premunire',24664,NULL,'821:21:05',NULL,-29284,'rapidestrapidestrapidestrapidestrapidestrapidestrapidest','convectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorconvectorcon',-3808,'intuitively','0000-00-00 00:00:00',-22296,NULL,'2802',28786,NULL,NULL,'loanword',-12107,'deodori','strophe','0000-00-00',-11013,'undeclared',-8513,'sinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'ssinuosity\'s','peloria\'s','14940','blushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblushblush','30550','11566',127,'00:00:00','worktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'sworktable\'swo','looker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'slooker\'s','5657-05-11',23094,'onerousness','bearer','censured','Shoemaker','mulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomulattomul',5930,'ZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoustZlatoust','1953-04-28 11:55:44','consulted','invalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinvalidity\'sinv',-27798,'carnauba\'s','Wilson',1963,NULL,'On\'s','leisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurelyleisurely',NULL,-128,NULL,17674,'Queenstown\'s',-128,'convertors',1776,'576:20:59',NULL,'allegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriallegriall','2097-10-02 08:41:26',31057,'AfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikanersAfrikaners','test1','0000-00-00 00:00:00','0000-00-00','backwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbackwardsbac',NULL,NULL,'1932-10-01 18:49:04',12985,NULL,'leukocytes','603:54:26',-22488);
+INSERT INTO `table5` VALUES ('Frasquito\'s','unsatisfactory','jetted','00:00:00',NULL,'Merlin\'s',127,'0000-00-00 00:00:00',NULL,NULL,1998,'','decomposer','Commons',-14813,'oversimplification\'s',NULL,'-5368','','engirdengirdengirdengirdengirdengirdengirdengirdengird',-13627,14305,'frontally',127,'18421',-32295,NULL,NULL,'21841',NULL,'0000-00-00','cytology','2424-00-17',-30542,-17621,'octarchy\'s','outfoxed','00:00:00',27469,-128,'','Kamat\'s',-24130,-5948,'riband','Betsy',NULL,-18769,NULL,NULL,'Serafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSerafina\'sSeraf',NULL,'disconcerting',NULL,'whirly','-20343','2020-07-01 12:09:36','','-26975','antiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticantiphlogisticant',NULL,'ecumenically','utilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilizerutilize','1952-08-01 17:53:28','7903',-5633,'2024-03-17 13:46:59','-5474',127,'Malmö\'s',NULL,NULL,'0000-00-00','571:58:00',17287,'26711','alphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetizealphabetize',-15158,2001,1997,'hobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithobbithob','Campinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'sCampinas\'s',-5693,'test1','3741','','Audrye\'s','monstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymonstrouslymo','00:00:00','test1','-21023',4693,'1998-01-06 04:41:40','Silastic\'s','0000-00-00 00:00:00','0000-00-00 00:00:00','Hedelman\'s',-30080,'normalization\'s','00:00:00',NULL,8197,NULL,NULL,NULL,'nudism\'s','2005-04-13 00:31:55',29046,'8992','11992',NULL,'-1685',-11453,'mythology\'s',26185,'Pyrenea','Pedrick\'s','0000-00-00',27436,'shots',NULL,'discordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscordsdiscords','bayonet','-7217','scriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscriptsscripts',NULL,'17182',NULL,'628:49:55','nunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenunclenuncle',NULL,'0000-00-00',-17444,'celestite\'s','Adars','Hispaniola','Mesopotamians','agglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutinativeagglutin',31998,'electrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistrieselectrochemistriesele','2005-09-09 23:41:06','bastinaded',NULL,-10763,'impetuosity\'s','xenogenesis\'s',1947,'-29913',NULL,'taxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomiestaxonomies',NULL,NULL,'internees',28697,'Kharkov\'s',NULL,'Swabia',18366,'00:00:00','delayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayerdelayer','circusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycircusycir','2066-02-13 14:27:00',-28405,NULL,'test1','0000-00-00 00:00:00','0000-00-00','heterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotrophicheterotr','enchondromaenchondromaenchondromaenchondromaenchondromaenchondromaenchondromaenchondroma','AryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAryAry','2090-10-13 10:03:05',NULL,NULL,'Yucatan','285:37:51',7627);
+/*!40000 ALTER TABLE `table5` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+
+#explain select * from `table5` where (col2 <= '6566-06-15' AND col24 <> 'd') group by `col83` order by `col83` desc ;
+
+select * from `table5` where (col2 <= '6566-06-15' AND col24 <> 'd') group by `col83` order by `col83` desc ;
+
+drop table `table5`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug43101.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43101.test
new file mode 100644
index 00000000000..7dd921806bf
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43101.test
@@ -0,0 +1,41 @@
+# Test for BUG#43101 "MyISAM&Maria gives rows for <>NULL and >NULL
+# with LIMIT clause"
+
+--source include/have_debug.inc
+
+# Goes away with
+#set session debug=+d,optimizer_no_icp;
+
+CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY
+KEY(c1), UNIQUE INDEX(c2));
+
+insert into t1 values('-838:59:59','-838:59:59','2009-01-21');
+insert into t1 values('00:00:00','00:00:00','2009-01-09');
+insert into t1 values('00:00:11','00:00:11','2009-01-20');
+insert into t1 values('00:00:12','00:00:12','2009-01-13');
+insert into t1 values('00:00:45','00:00:45','2009-01-07');
+insert into t1 values('00:11:12','00:11:12','2009-01-19');
+insert into t1 values('00:12:30','00:12:30','2009-01-23');
+insert into t1 values('00:12:34','00:12:34','2009-01-14');
+insert into t1 values('01:23:00','01:23:00','2009-01-03');
+insert into t1 values('08:03:02','08:03:02','2009-01-18');
+insert into t1 values('08:29:45',NULL,'2009-02-01');
+insert into t1 values('09:00:45','09:00:45','2009-01-24');
+insert into t1 values('09:36:00','09:36:00','2009-01-25');
+insert into t1 values('10:00:00','10:00:00','2009-01-06');
+insert into t1 values('10:11:12','10:11:12','2009-01-11');
+insert into t1 values('10:22:33','10:22:33','2009-01-02');
+insert into t1 values('11:11:12','11:11:12','2009-01-12');
+insert into t1 values('11:11:27','11:11:27','2009-01-17');
+insert into t1 values('12:34:56','12:34:56','2009-01-01');
+insert into t1 values('12:34:58','12:34:58','2009-01-15');
+insert into t1 values('12:35:56','12:35:56','2009-01-16');
+insert into t1 values('491:22:33','491:22:33','2009-01-04');
+insert into t1 values('825:23:00','825:23:00','2009-01-05');
+insert into t1 values('838:59:59','838:59:59','2009-01-21');
+
+SELECT * FROM t1 WHERE c2 <> NULL ORDER BY c2 DESC;
+
+SELECT * FROM t1 WHERE c2 <> NULL ORDER BY c2 DESC LIMIT 2;
+
+drop table t1;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug43249.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43249.test
new file mode 100644
index 00000000000..827220b0a6f
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43249.test
@@ -0,0 +1,17 @@
+# Test for BUG#43249 "Innodb returns zero time for the time column
+# with <=> NULL order by limit"
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+set session debug="+d,optimizer_innodb_icp";
+
+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');
+# first time, good results:
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c2 LIMIT 2;
+# second time, bad results:
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c2 LIMIT 2;
+
+drop table `t1`;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug43360.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43360.test
new file mode 100644
index 00000000000..0d1e4740712
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43360.test
@@ -0,0 +1,44 @@
+
+--echo #
+--echo # Bug#43360 - Server crash with a simple multi-table update
+--echo #
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+# crash requires this
+set session debug="+d,optimizer_innodb_icp";
+
+CREATE TABLE t1 (
+ a CHAR(2) NOT NULL PRIMARY KEY,
+ b VARCHAR(20) NOT NULL,
+ KEY (b)
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+ a CHAR(2) NOT NULL PRIMARY KEY,
+ b VARCHAR(20) NOT NULL,
+ KEY (b)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+('AB','MySQLAB'),
+('JA','Sun Microsystems'),
+('MS','Microsoft'),
+('IB','IBM- Inc.'),
+('GO','Google Inc.');
+
+INSERT INTO t2 VALUES
+('AB','Sweden'),
+('JA','USA'),
+('MS','United States of America'),
+('IB','North America'),
+('GO','South America');
+
+UPDATE t1,t2 SET t1.b=UPPER(t1.b) WHERE t1.b LIKE 'United%';
+
+SELECT * FROM t1;
+
+SELECT * FROM t2;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug43448.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43448.test
new file mode 100644
index 00000000000..0daa1c3c739
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43448.test
@@ -0,0 +1,58 @@
+--echo #
+--echo # Bug#43448 - Server crashes on multi table delete with Innodb
+--echo #
+
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+# crash requires ICP support in InnoDB
+set session debug="+d,optimizer_innodb_icp";
+
+CREATE TABLE t1 (
+ id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ t CHAR(12)
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+ id2 INT NOT NULL,
+ t CHAR(12)
+) ENGINE=InnoDB;
+
+CREATE TABLE t3(
+ id3 INT NOT NULL,
+ t CHAR(12),
+ INDEX(id3)
+) ENGINE=InnoDB;
+
+disable_query_log;
+
+let $1 = 100;
+while ($1)
+{
+ let $2 = 5;
+ eval INSERT INTO t1(t) VALUES ('$1');
+ while ($2)
+ {
+ eval INSERT INTO t2(id2,t) VALUES ($1,'$2');
+ let $3 = 10;
+ while ($3)
+ {
+ eval INSERT INTO t3(id3,t) VALUES ($1,'$2');
+ dec $3;
+ }
+ dec $2;
+ }
+ dec $1;
+}
+
+enable_query_log;
+
+SELECT COUNT(*) FROM t1 WHERE id1 > 90;
+SELECT COUNT(*) FROM t2 WHERE id2 > 90;
+SELECT COUNT(*) FROM t3 WHERE id3 > 90;
+
+DELETE t1, t2, t3
+FROM t1, t2, t3
+WHERE t1.id1 = t2.id2 AND t2.id2 = t3.id3 AND t1.id1 > 5;
+
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug43617.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43617.test
new file mode 100644
index 00000000000..2b3b65577af
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43617.test
@@ -0,0 +1,86 @@
+# test for BUG#43617 "Innodb returns wrong results with timestamp's
+# range value in IN clause"
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+set storage_engine=innodb;
+set @save_time_zone= @@time_zone;
+set time_zone='+03:00';
+set session debug="+d,optimizer_innodb_icp";
+
+######## Running INSERT tests for TIMESTAMP ########
+
+# Create tables
+CREATE TABLE t1(c1 TIMESTAMP NOT NULL, c2 TIMESTAMP NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1), UNIQUE INDEX(c2));
+
+# Insert some rows with targeted values
+
+# As a string in either 'YYYY-MM-DD HH:MM:SS', 'YY-MM-DD HH:MM:SS', 'YYYY-MM-DD' or 'YY-MM-DD' format
+INSERT INTO t1 VALUES('98-12-31 11:30:45','98.12.31 11+30+45','98-12-31 11:30:45','98.12.31 11+30+45'),('98/12/30 11*30*45','98@12@30 11^30^45','98/12/30 11*30*45','98@12@30 11^30^45'),('98-12-29','98.12.29','98-12-29','98.12.29'),('98/12/28','98@12@28','98/12/28','98@12@28');
+
+# As a string with no delimiters in either 'YYYYMMDDHHMMSS', 'YYMMDDHHMMSS', 'YYYYMMDD' or 'YYMMDD' format
+INSERT INTO t1 VALUES('20070523091528','070523091528','20070524091528','070524091528'),('20070525','070525','20070526','070526');
+
+# As a number in either YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD or YYMMDD format
+INSERT INTO t1 VALUES(19830905132800,830905132800,19830906132800,830906132800),(19830907,830907,19830908,830908);
+
+# As the result of a function
+SET TIMESTAMP=1233216687; # 2009-01-29 13:41:27
+INSERT INTO t1 VALUES(NOW(),CURRENT_DATE,NOW(),CURRENT_DATE);
+
+# Insert permissible NULLs
+INSERT INTO t1 VALUES('2008-01-01',NULL,'08-01-02','08/01/03');
+
+# Insert duplicate NULLs to unique column
+INSERT INTO t1(c1,c2) VALUES('08/01/17',NULL);
+DELETE FROM t1 WHERE c1='08/01/17' AND c2 IS NULL;
+
+# Insert empty string '', would be converted to zero value of the appropriate type
+INSERT INTO t1 VALUES('','','08-01-04','08/01/05') /* Inserts zero dates for '' strings */;
+
+--sorted_result
+SELECT * FROM t1;
+
+# Test 'INSERT IGNORE' with the same rows that reported constraint violation above
+# Ignore pk constraint
+INSERT IGNORE INTO t1(c1,c2) VALUES('20070525','20070527') /* doesnt throw error */;
+
+# Ignore unique constraint
+INSERT IGNORE INTO t1(c1,c2) VALUES(19840905,830907) /* doesnt throw error */;
+
+# Test 'INSERT ON DUPLICATE KEY UPDATE' with single column PK
+SELECT * FROM t1 WHERE c1='20070527' /* Returns no rows */;
+INSERT INTO t1(c1) VALUES('20070525') ON DUPLICATE KEY UPDATE c1='20070527';
+SELECT * FROM t1 WHERE c1='20070527' /* Returns 1 row with c1=2007-05-27 */;
+
+# Test 'INSERT ON DUPLICATE KEY UPDATE' with single column unique
+SELECT * FROM t1 WHERE c1=19830909 AND c2=830910 /* Returns no rows */;
+INSERT INTO t1(c1,c2) VALUES(19840905,830907) ON DUPLICATE KEY UPDATE c1=19830909,c2=830910;
+SELECT * FROM t1 WHERE c1=19830909 AND c2=830910 /* Returns 1 row */;
+
+# Test 'INSERT SET'
+INSERT INTO t1 SET c1='1999-01-01',c2='1999-01-01';
+SELECT * FROM t1 WHERE c1='1999-01-01' AND c2='1999-01-01' /* Returns 1 row with values for other column as NULL */;
+
+# Test insert range values to 'TIMESTAMP' columns
+INSERT INTO t1 VALUES('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02'),('1990-01-01 00:00:01','2000-01-01 00:00:01','2009-01-03','2009-01-04'),('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06');
+
+# Test insert NULL to non-null column
+# Inserting NULL to TIMESTAMP NOT NULL field doesn't throw error, but records the current/set timestamp
+
+DELETE FROM t1 WHERE c1=NOW() /* because the row with current timestamp exists */;
+INSERT INTO t1 VALUES(NULL,NOW(),NOW(),NOW());
+SELECT * FROM t1 WHERE c1 IS NULL /* returns no rows */;
+SELECT * FROM t1 WHERE c1=NOW() /* returns 1 row */;
+
+--sorted_result
+SELECT * FROM t1;
+
+SELECT * FROM t1 WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07') ORDER BY c2;
+SELECT * FROM t1 WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07') ORDER BY c2 LIMIT 2;
+SELECT * FROM t1 WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07') ORDER BY c2 DESC;
+SELECT * FROM t1 WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07') ORDER BY c2 DESC LIMIT 2;
+DROP TABLE t1;
+
+set time_zone= @save_time_zone;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug43618.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43618.test
new file mode 100644
index 00000000000..e05ea3ee4f5
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43618.test
@@ -0,0 +1,49 @@
+# test for BUG#43618 "MyISAM&Maria returns wrong results with
+# 'between' on timestamp"
+
+--source include/have_debug.inc
+
+set @save_time_zone= @@time_zone;
+set time_zone='+03:00';
+# bug goes away with
+#set session debug="+d,optimizer_no_icp";
+
+######## Running INSERT tests for TIMESTAMP ########
+
+# Create tables
+CREATE TABLE t1(c1 TIMESTAMP NOT NULL, c2 TIMESTAMP NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1), UNIQUE INDEX(c2));
+
+# Insert some rows with targeted values
+
+# As a string in either 'YYYY-MM-DD HH:MM:SS', 'YY-MM-DD HH:MM:SS', 'YYYY-MM-DD' or 'YY-MM-DD' format
+INSERT INTO t1 VALUES('98-12-31 11:30:45','98.12.31 11+30+45','98-12-31 11:30:45','98.12.31 11+30+45'),('98/12/30 11*30*45','98@12@30 11^30^45','98/12/30 11*30*45','98@12@30 11^30^45'),('98-12-29','98.12.29','98-12-29','98.12.29'),('98/12/28','98@12@28','98/12/28','98@12@28');
+
+# As a string with no delimiters in either 'YYYYMMDDHHMMSS', 'YYMMDDHHMMSS', 'YYYYMMDD' or 'YYMMDD' format
+INSERT INTO t1 VALUES('20070523091528','070523091528','20070524091528','070524091528'),('20070525','070525','20070526','070526');
+
+# As a number in either YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD or YYMMDD format
+INSERT INTO t1 VALUES(19830905132800,830905132800,19830906132800,830906132800),(19830907,830907,19830908,830908);
+
+# As the result of a function
+SET TIMESTAMP=1233216687; # 2009-01-29 13:41:27
+INSERT INTO t1 VALUES(NOW(),CURRENT_DATE,NOW(),CURRENT_DATE);
+
+# Insert permissible NULLs
+INSERT INTO t1 VALUES('2008-01-01',NULL,'08-01-02','08/01/03');
+
+# Insert duplicate NULLs to unique column
+INSERT INTO t1(c1,c2) VALUES('08/01/17',NULL);
+DELETE FROM t1 WHERE c1='08/01/17' AND c2 IS NULL;
+
+# Insert empty string '', would be converted to zero value of the appropriate type
+INSERT INTO t1 VALUES('','','08-01-04','08/01/05') /* Inserts zero dates for '' strings */;
+
+INSERT INTO t1 VALUES('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02'),('1990-01-01 00:00:01','2000-01-01 00:00:01','2009-01-03','2009-01-04'),('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06');
+
+--sorted_result
+SELECT * FROM t1;
+SELECT * FROM t1 WHERE c1 BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY c1 DESC LIMIT 2;
+SELECT * FROM t1 WHERE c2 BETWEEN '1971-01-01 00:00:01' AND '2010-10-00 00:00:00' ORDER BY c2 DESC LIMIT 2;
+DROP TABLE t1;
+set time_zone= @save_time_zone;
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug45219.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug45219.test
new file mode 100644
index 00000000000..85e24824afc
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug45219.test
@@ -0,0 +1,183 @@
+# BUG#45219 "Azalea crash on query containing a JOIN in subquery"
+
+# Both SELECT DISTINCT cause similar crashes.
+# With ./mtr --mysqld=--optimizer_switch="semijoin=off" optimizer_unfixed_bugs.bug45219
+# there is no crash, the result file has been created with this
+# command, but it has *not* been checked for correctness of returned
+# data (at least 5.1 gives the same result).
+
+
+# Begin test case for query 0
+
+--disable_warnings
+DROP TABLE IF EXISTS CC, C, BB;
+--enable_warnings
+
+CREATE TABLE `CC` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES
+(10,0,'2006-07-07 07:26:28','q'),(11,5,'2002-09-23 00:00:00','m'),
+(12,7,'0000-00-00 00:00:00','j'),(13,1,'2006-06-07 00:00:00','z'),
+(14,8,'2000-09-16 12:15:34','a'),(15,2,'2007-08-05 15:47:52',''),
+(16,1,'0000-00-00 00:00:00','e'),(17,8,'2005-12-02 19:34:26','t'),
+(18,5,'0000-00-00 00:00:00','q'),(19,4,'0000-00-00 00:00:00','b'),
+(20,5,'2007-12-28 00:00:00','w'),(21,3,'2004-08-02 11:48:43','m'),
+(22,0,'0000-00-00 00:00:00','x'),(23,8,'2004-04-19 12:18:43',''),
+(24,0,'2009-04-27 00:00:00','w'),(25,4,'2006-10-20 14:52:15','x'),
+(26,0,'0000-00-00 00:00:00','e'),(27,0,'2002-03-22 11:48:37','e'),
+(28,2,'0000-00-00 00:00:00','p'),(29,0,'2001-01-04 03:55:07','x');
+CREATE TABLE `C` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES
+(1,9,'0000-00-00 00:00:00','p'),(2,0,'2002-02-09 07:38:13','v'),
+(3,8,'2001-05-03 12:08:14','t'),(4,3,'0000-00-00 00:00:00','u'),
+(5,7,'2009-07-28 03:43:30','n'),(6,0,'2009-08-04 00:00:00','l'),
+(7,1,'0000-00-00 00:00:00','h'),(8,9,'0000-00-00 00:00:00','u'),
+(9,0,'2005-08-02 17:16:54','n'),(10,9,'2002-12-21 00:00:00','j'),
+(11,0,'2005-08-15 12:37:35','k'),(12,5,'0000-00-00 00:00:00','e'),
+(13,0,'2006-03-10 00:00:00','i'),(14,8,'2005-05-16 11:02:36','u'),
+(15,8,'2008-11-02 00:00:00','n'),(16,5,'2006-03-15 00:00:00','b'),
+(17,1,'0000-00-00 00:00:00','x'),(18,7,'0000-00-00 00:00:00',''),
+(19,0,'2008-12-17 20:15:40','q'),(20,9,'0000-00-00 00:00:00','u');
+CREATE TABLE `BB` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `BB` VALUES
+(10,8,'2007-08-19 08:08:38','i'),(11,0,'2000-05-21 03:51:51','');
+
+SELECT DISTINCT `datetime_key`
+FROM C
+WHERE ( `int_nokey` , `pk` ) IN (
+SELECT INNR .`pk` , INNR .`pk`
+FROM CC LEFT JOIN BB INNR ON INNR .`varchar_key` ) AND `pk` = 9 ;
+
+DROP TABLE CC, C, BB;
+
+# End of test case for query 0
+
+# Begin test case for query 1
+
+--disable_warnings
+DROP TABLE IF EXISTS CC, C, BB;
+--enable_warnings
+
+CREATE TABLE `CC` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `int_key` int(11) NOT NULL,
+ `date_key` date NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ `varchar_nokey` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `date_key` (`date_key`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES
+(10,0,8,'2007-02-14','2006-07-07 07:26:28','q','q'),
+(11,5,8,'2002-10-03','2002-09-23 00:00:00','m','m'),
+(12,7,3,'2006-12-02','0000-00-00 00:00:00','j','j'),
+(13,1,2,'2007-05-02','2006-06-07 00:00:00','z','z'),
+(14,8,2,'2001-11-18','2000-09-16 12:15:34','a','a'),
+(15,2,6,'2006-09-09','2007-08-05 15:47:52','',''),
+(16,1,8,'0000-00-00','0000-00-00 00:00:00','e','e'),
+(17,8,9,'2003-07-22','2005-12-02 19:34:26','t','t'),
+(18,5,2,'2001-12-22','0000-00-00 00:00:00','q','q'),
+(19,4,6,'0000-00-00','0000-00-00 00:00:00','b','b'),
+(20,5,5,'2006-09-02','2007-12-28 00:00:00','w','w'),
+(21,3,2,'0000-00-00','2004-08-02 11:48:43','m','m'),
+(22,0,4,'0000-00-00','0000-00-00 00:00:00','x','x'),
+(23,8,9,'2001-02-28','2004-04-19 12:18:43','',''),
+(24,0,6,'0000-00-00','2009-04-27 00:00:00','w','w'),
+(25,4,5,'2007-05-19','2006-10-20 14:52:15','x','x'),
+(26,0,0,'2005-02-15','0000-00-00 00:00:00','e','e'),
+(27,0,0,'2000-10-19','2002-03-22 11:48:37','e','e'),
+(28,2,8,'2005-07-07','0000-00-00 00:00:00','p','p'),
+(29,0,0,'2008-10-18','2001-01-04 03:55:07','x','x');
+CREATE TABLE `C` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `int_key` int(11) NOT NULL,
+ `date_key` date NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ `varchar_nokey` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `date_key` (`date_key`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES
+(1,9,9,'2007-12-01','0000-00-00 00:00:00','p','p'),
+(2,0,0,'0000-00-00','2002-02-09 07:38:13','v','v'),
+(3,8,6,'0000-00-00','2001-05-03 12:08:14','t','t'),
+(4,3,6,'2002-05-07','0000-00-00 00:00:00','u','u'),
+(5,7,6,'0000-00-00','2009-07-28 03:43:30','n','n'),
+(6,0,4,'0000-00-00','2009-08-04 00:00:00','l','l'),
+(7,1,7,'0000-00-00','0000-00-00 00:00:00','h','h'),
+(8,9,4,'0000-00-00','0000-00-00 00:00:00','u','u'),
+(9,0,8,'0000-00-00','2005-08-02 17:16:54','n','n'),
+(10,9,4,'2000-12-18','2002-12-21 00:00:00','j','j'),
+(11,0,7,'2005-11-13','2005-08-15 12:37:35','k','k'),
+(12,5,5,'0000-00-00','0000-00-00 00:00:00','e','e'),
+(13,0,0,'2003-11-12','2006-03-10 00:00:00','i','i'),
+(14,8,5,'2006-02-20','2005-05-16 11:02:36','u','u'),
+(15,8,7,'2005-02-12','2008-11-02 00:00:00','n','n'),
+(16,5,2,'2009-07-20','2006-03-15 00:00:00','b','b'),
+(17,1,8,'2005-02-24','0000-00-00 00:00:00','x','x'),
+(18,7,0,'0000-00-00','0000-00-00 00:00:00','',''),
+(19,0,9,'0000-00-00','2008-12-17 20:15:40','q','q'),
+(20,9,5,'0000-00-00','0000-00-00 00:00:00','u','u');
+CREATE TABLE `BB` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `int_key` int(11) NOT NULL,
+ `date_key` date NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ `varchar_nokey` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `date_key` (`date_key`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `BB` VALUES (10,8,5,'0000-00-00','2007-08-19
+08:08:38','i','i'),(11,0,8,'2005-08-18','2000-05-21 03:51:51','','');
+
+SELECT DISTINCT BIT_AND( OUTR . `datetime_key` ) AS X
+FROM C AS OUTR
+WHERE ( OUTR . `int_nokey` , OUTR . `pk` ) IN (
+SELECT DISTINCT INNR . `pk` AS X , INNR . `pk` AS Y
+FROM CC AS INNR2 LEFT JOIN BB AS INNR ON
+( INNR2 . `varchar_nokey` = INNR . `varchar_key` )
+WHERE INNR . `date_key` BETWEEN '2009-04-26' AND '2004-08-21' )
+AND OUTR . `pk` = 9
+ORDER BY OUTR . `int_key` , OUTR . `pk`;
+
+DROP TABLE CC, C, BB;
+
+# End of test case for query 1
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug45221.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug45221.test
new file mode 100644
index 00000000000..e60c7818b19
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug45221.test
@@ -0,0 +1,97 @@
+# test for BUG#45221 "Query "SELECT pk FROM C WHERE pk IN (SELECT
+# int_key)" failing"
+
+--source include/have_debug.inc
+
+# bug goes away with
+#set session debug="+d,optimizer_no_icp";
+
+# those don't remove the problem but make the result diff different:
+#set optimizer_switch="materialization=off";
+#set optimizer_switch="semijoin=off";
+#set optimizer_switch="materialization=off,semijoin=off";
+
+#/* Begin test case for query 0 */
+
+CREATE TABLE `CC` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_key` int(11) DEFAULT NULL,
+ `date_nokey` date DEFAULT NULL,
+ `datetime_nokey` datetime DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES (10,8,NULL,'2002-02-26 06:14:37'),(11,9,'2006-06-14','1900-01-01 00:00:00'),(12,9,'2002-09-12','2006-12-03 09:37:26'),(13,186,'2005-02-15','2008-05-26 12:27:10'),(14,NULL,NULL,'2004-12-14 16:37:30'),(15,2,'2008-11-04','2003-02-11 21:19:41'),(16,3,'2004-09-04','2009-10-18 02:27:49'),(17,0,'2006-06-05','2000-09-26 07:45:57'),(18,133,'1900-01-01',NULL),(19,1,'1900-01-01','2005-11-10 12:40:29'),(20,8,'1900-01-01','2009-04-25 00:00:00'),(21,5,'2005-01-13','2002-11-27 00:00:00'),(22,5,'2006-05-21','2004-01-26 20:32:32'),(23,8,'2003-09-08','2007-10-26 11:41:40'),(24,6,'2006-12-23','2005-10-07 00:00:00'),(25,51,'2006-10-15','2000-07-15 05:00:34'),(26,4,'2005-04-06','2000-04-03 16:33:32'),(27,7,'2008-04-07',NULL),(28,6,'2006-10-10','2001-04-25 01:26:12'),(29,4,'1900-01-01','2000-12-27 00:00:00');
+CREATE TABLE `C` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_key` int(11) DEFAULT NULL,
+ `date_nokey` date DEFAULT NULL,
+ `datetime_nokey` datetime DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES (1,2,NULL,'2004-10-11 18:13:16'),(2,9,'2001-09-19',NULL),(3,3,'2004-09-12','1900-01-01 00:00:00'),(4,9,NULL,'2009-07-25 00:00:00'),(5,NULL,'2002-07-19',NULL),(6,9,'2002-12-16','2008-07-27 00:00:00'),(7,3,'2006-02-08','2002-11-13 16:37:31'),(8,8,'2006-08-28','1900-01-01 00:00:00'),(9,8,'2001-04-14','2003-12-10 00:00:00'),(10,53,'2000-01-05','2001-12-21 22:38:22'),(11,0,'2003-12-06','2008-12-13 23:16:44'),(12,5,'1900-01-01','2005-08-15 12:39:41'),(13,166,'2002-11-27',NULL),(14,3,NULL,'2006-09-11 12:06:14'),(15,0,'2003-05-27','2007-12-15 12:39:34'),(16,1,'2005-05-03','2005-08-09 00:00:00'),(17,9,'2001-04-18','2001-09-02 22:50:02'),(18,5,'2005-12-27','2005-12-16 22:58:11'),(19,6,'2004-08-20','2007-04-19 00:19:53'),(20,2,'1900-01-01','1900-01-01 00:00:00');
+
+SELECT `pk`
+FROM C OUTR
+WHERE `pk` IN (
+SELECT `int_key`
+FROM CC
+WHERE `date_nokey` < `datetime_nokey` XOR OUTR .`date_nokey` ) ;
+
+SELECT `pk`
+FROM C
+WHERE `pk` IN (
+SELECT `int_key`
+FROM CC
+WHERE `date_nokey` < `datetime_nokey` XOR '2009-11-25' ) ;
+
+DROP TABLE CC;
+DROP TABLE C;
+#/* End of test case for query 0 */
+
+#/* Begin test case for query 1 */
+
+CREATE TABLE `CC` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) DEFAULT NULL,
+ `int_key` int(11) DEFAULT NULL,
+ `date_nokey` date DEFAULT NULL,
+ `datetime_key` datetime DEFAULT NULL,
+ `datetime_nokey` datetime DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `CC` VALUES (10,7,8,NULL,'2002-02-26 06:14:37','2002-02-26 06:14:37'),(11,1,9,'2006-06-14','1900-01-01 00:00:00','1900-01-01 00:00:00'),(12,5,9,'2002-09-12','2006-12-03 09:37:26','2006-12-03 09:37:26'),(13,3,186,'2005-02-15','2008-05-26 12:27:10','2008-05-26 12:27:10'),(14,6,NULL,NULL,'2004-12-14 16:37:30','2004-12-14 16:37:30'),(15,92,2,'2008-11-04','2003-02-11 21:19:41','2003-02-11 21:19:41'),(16,7,3,'2004-09-04','2009-10-18 02:27:49','2009-10-18 02:27:49'),(17,NULL,0,'2006-06-05','2000-09-26 07:45:57','2000-09-26 07:45:57'),(18,3,133,'1900-01-01',NULL,NULL),(19,5,1,'1900-01-01','2005-11-10 12:40:29','2005-11-10 12:40:29'),(20,1,8,'1900-01-01','2009-04-25 00:00:00','2009-04-25 00:00:00'),(21,2,5,'2005-01-13','2002-11-27 00:00:00','2002-11-27 00:00:00'),(22,NULL,5,'2006-05-21','2004-01-26 20:32:32','2004-01-26 20:32:32'),(23,1,8,'2003-09-08','2007-10-26 11:41:40','2007-10-26 11:41:40'),(24,0,6,'2006-12-23','2005-10-07 00:00:00','2005-10-07 00:00:00'),(25,210,51,'2006-10-15','2000-07-15 05:00:34','2000-07-15 05:00:34'),(26,8,4,'2005-04-06','2000-04-03 16:33:32','2000-04-03 16:33:32'),(27,7,7,'2008-04-07',NULL,NULL),(28,5,6,'2006-10-10','2001-04-25 01:26:12','2001-04-25 01:26:12'),(29,NULL,4,'1900-01-01','2000-12-27 00:00:00','2000-12-27 00:00:00');
+CREATE TABLE `C` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) DEFAULT NULL,
+ `int_key` int(11) DEFAULT NULL,
+ `date_nokey` date DEFAULT NULL,
+ `datetime_key` datetime DEFAULT NULL,
+ `datetime_nokey` datetime DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `C` VALUES (1,NULL,2,NULL,'2004-10-11 18:13:16','2004-10-11 18:13:16'),(2,7,9,'2001-09-19',NULL,NULL),(3,9,3,'2004-09-12','1900-01-01 00:00:00','1900-01-01 00:00:00'),(4,7,9,NULL,'2009-07-25 00:00:00','2009-07-25 00:00:00'),(5,4,NULL,'2002-07-19',NULL,NULL),(6,2,9,'2002-12-16','2008-07-27 00:00:00','2008-07-27 00:00:00'),(7,6,3,'2006-02-08','2002-11-13 16:37:31','2002-11-13 16:37:31'),(8,8,8,'2006-08-28','1900-01-01 00:00:00','1900-01-01 00:00:00'),(9,NULL,8,'2001-04-14','2003-12-10 00:00:00','2003-12-10 00:00:00'),(10,5,53,'2000-01-05','2001-12-21 22:38:22','2001-12-21 22:38:22'),(11,NULL,0,'2003-12-06','2008-12-13 23:16:44','2008-12-13 23:16:44'),(12,6,5,'1900-01-01','2005-08-15 12:39:41','2005-08-15 12:39:41'),(13,188,166,'2002-11-27',NULL,NULL),(14,2,3,NULL,'2006-09-11 12:06:14','2006-09-11 12:06:14'),(15,1,0,'2003-05-27','2007-12-15 12:39:34','2007-12-15 12:39:34'),(16,1,1,'2005-05-03','2005-08-09 00:00:00','2005-08-09 00:00:00'),(17,0,9,'2001-04-18','2001-09-02 22:50:02','2001-09-02 22:50:02'),(18,9,5,'2005-12-27','2005-12-16 22:58:11','2005-12-16 22:58:11'),(19,NULL,6,'2004-08-20','2007-04-19 00:19:53','2007-04-19 00:19:53'),(20,4,2,'1900-01-01','1900-01-01 00:00:00','1900-01-01 00:00:00');
+
+SELECT OUTR . `pk` AS X
+FROM C AS OUTR
+WHERE OUTR . `pk` IN (
+SELECT INNR . `int_key` AS Y
+FROM CC AS INNR
+WHERE INNR . `date_nokey` < INNR . `datetime_nokey` XOR OUTR . `date_nokey` BETWEEN '2004-07-10' AND '2009-11-25'
+ORDER BY INNR . `int_nokey` ) AND ( OUTR . `datetime_key` BETWEEN '2000-05-25' AND '2004-08-07' OR OUTR . `datetime_nokey` = '2007-10-24' )
+ORDER BY OUTR . `int_key` , OUTR . `pk`;
+
+
+DROP TABLE CC;
+DROP TABLE C;
+#/* End of test case for query 1 */
+
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/bug49129.test b/mysql-test/suite/optimizer_unfixed_bugs/t/bug49129.test
new file mode 100644
index 00000000000..e0e7179afa1
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug49129.test
@@ -0,0 +1,34 @@
+SET SESSION optimizer_switch = 'firstmatch=off,index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,loosescan=on,materialization=on,semijoin=on';
+
+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;
+
+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;
+UPDATE t2 SET b=11 WHERE a=3;
+
+--echo
+--echo # This result is wrong, but will be fixed by Bug#46556
+SELECT * FROM t0 WHERE t0.a IN
+ (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+SET join_cache_level = 6;
+
+--echo
+--echo # This result is even more wrong ;-)
+SELECT * FROM t0 WHERE t0.a IN
+ (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+SET SESSION optimizer_switch = 'semijoin=off';
+
+--echo
+--echo # This result is correct
+SELECT * FROM t0 WHERE t0.a IN
+ (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+DROP TABLE t0, t1, t2;
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/t/disabled.def b/mysql-test/suite/optimizer_unfixed_bugs/t/disabled.def
new file mode 100644
index 00000000000..4aaca8adc09
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/disabled.def
@@ -0,0 +1,7 @@
+# Disabling all subquery problems
+
+bug49129 : Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
+bug45221 : Query "SELECT pk FROM C WHERE pk IN (SELECT # int_key)" failing
+bug45219 : Azalea crash on query containing a JOIN in subquery
+
+
diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result
index e73dd6609dc..64a18188888 100644
--- a/mysql-test/suite/parts/r/partition_special_innodb.result
+++ b/mysql-test/suite/parts/r/partition_special_innodb.result
@@ -31,9 +31,9 @@ a b c d
2000-06-15 jukg zikhuk m
select * from t1 where a<19851231;
a b c d
-1983-12-31 cdef srtbvsr w
-1980-10-14 fgbbd dtzndtz w
1975-01-01 abcde abcde m
+1980-10-14 fgbbd dtzndtz w
+1983-12-31 cdef srtbvsr w
drop table t1;
create table t1 (a date not null, b varchar(50) not null, c varchar(50) not null, d enum('m', 'w') not null, e int not null, f decimal (18,2) not null, g bigint not null, h tinyint not null, i char(255), primary key(a,b,c,d,e,f,g,h)) engine='InnoDB'
partition by key(a,b,c,d,e,f,g,h) (
@@ -73,9 +73,9 @@ a b c d e f g h i
2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m
select * from t1 where a<19851231;
a b c d e f g h i
+1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
-1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
drop table t1;
create table t1 (a date not null, b varchar(50) not null, c varchar(50) not null, d enum('m', 'w') not null, e int not null, f decimal (18,2) not null, g bigint not null, h tinyint not null, a1 date not null, b1 varchar(50) not null, c1 varchar(50) not null, d1 enum('m', 'w') not null, e1 int not null, f1 decimal (18,2) not null, g1 bigint not null, h1 tinyint not null, i char(255), primary key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1)) engine='InnoDB'
partition by key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1) (
@@ -123,9 +123,9 @@ a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i
2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m
select * from t1 where a<19851231;
a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i
-1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
-1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
+1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
+1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
drop table t1;
create table t1 (a date not null, b varchar(50) not null, c varchar(50) not null, d enum('m', 'w') not null, e int not null, f decimal (18,2) not null, g bigint not null, h tinyint not null, a1 date not null, b1 varchar(50) not null, c1 varchar(50) not null, d1 enum('m', 'w') not null, e1 int not null, f1 decimal (18,2) not null, g1 bigint not null, h1 tinyint not null, a2 date not null, b2 varchar(50) not null, c2 varchar(50) not null, d2 enum('m', 'w') not null, e2 int not null, f2 decimal (18,2) not null, g2 bigint not null, h2 tinyint not null, a3 date not null, b3 varchar(50) not null, c3 varchar(50) not null, d3 enum('m', 'w') not null, e3 int not null, f3 decimal (18,2) not null, g3 bigint not null, h3 tinyint not null, i char(255), primary key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1,a2,b2,c2,d2,e2,f2,g2,h2,a3,b3,c3,d3,e3,f3,g3,h3,a4)) engine='InnoDB'
partition by key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1,a2,b2,c2,d2,e2,f2,g2,h2,a3,b3,c3,d3,e3,f3,g3,h3,a4) (
@@ -203,9 +203,9 @@ a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f
2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m
select * from t1 where a<19851231;
a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f3 g3 h3 i
+1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
-1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
drop table t1;
# Bug#34604 - Assertion 'inited==RND' failed in handler::ha_rnd_end
CREATE TABLE t1 (
diff --git a/mysql-test/suite/parts/r/partition_special_myisam.result b/mysql-test/suite/parts/r/partition_special_myisam.result
index ca7f7aeb760..613f0716de4 100644
--- a/mysql-test/suite/parts/r/partition_special_myisam.result
+++ b/mysql-test/suite/parts/r/partition_special_myisam.result
@@ -73,9 +73,9 @@ a b c d e f g h i
2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m
select * from t1 where a<19851231;
a b c d e f g h i
+1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
-1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
drop table t1;
create table t1 (a date not null, b varchar(50) not null, c varchar(50) not null, d enum('m', 'w') not null, e int not null, f decimal (18,2) not null, g bigint not null, h tinyint not null, a1 date not null, b1 varchar(50) not null, c1 varchar(50) not null, d1 enum('m', 'w') not null, e1 int not null, f1 decimal (18,2) not null, g1 bigint not null, h1 tinyint not null, i char(255), primary key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1)) engine='MyISAM'
partition by key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1) (
@@ -123,9 +123,9 @@ a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i
2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m
select * from t1 where a<19851231;
a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i
-1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
-1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
+1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
+1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
drop table t1;
create table t1 (a date not null, b varchar(50) not null, c varchar(50) not null, d enum('m', 'w') not null, e int not null, f decimal (18,2) not null, g bigint not null, h tinyint not null, a1 date not null, b1 varchar(50) not null, c1 varchar(50) not null, d1 enum('m', 'w') not null, e1 int not null, f1 decimal (18,2) not null, g1 bigint not null, h1 tinyint not null, a2 date not null, b2 varchar(50) not null, c2 varchar(50) not null, d2 enum('m', 'w') not null, e2 int not null, f2 decimal (18,2) not null, g2 bigint not null, h2 tinyint not null, a3 date not null, b3 varchar(50) not null, c3 varchar(50) not null, d3 enum('m', 'w') not null, e3 int not null, f3 decimal (18,2) not null, g3 bigint not null, h3 tinyint not null, i char(255), primary key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1,a2,b2,c2,d2,e2,f2,g2,h2,a3,b3,c3,d3,e3,f3,g3,h3,a4)) engine='MyISAM'
partition by key(a,b,c,d,e,f,g,h,a1,b1,c1,d1,e1,f1,g1,h1,a2,b2,c2,d2,e2,f2,g2,h2,a3,b3,c3,d3,e3,f3,g3,h3,a4) (
@@ -203,7 +203,7 @@ a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f
2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m
select * from t1 where a<19851231;
a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f3 g3 h3 i
+1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr
1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi
-1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh
drop table t1;
diff --git a/mysql-test/suite/pbxt/r/derived.result b/mysql-test/suite/pbxt/r/derived.result
index fb723c45c0f..56d2f8ac929 100644
--- a/mysql-test/suite/pbxt/r/derived.result
+++ b/mysql-test/suite/pbxt/r/derived.result
@@ -58,7 +58,7 @@ a b a b
explain select * from t1 as x1, (select * from t1) as x2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY x1 ALL NULL NULL NULL NULL 4
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 4
drop table if exists t2,t3;
select * from (select 1) as a;
@@ -115,7 +115,7 @@ explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED t2 ALL NULL NULL NULL NULL 1
-2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
drop table t1, t2;
create table t1(a int not null, t char(8), index(a));
SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
@@ -143,7 +143,7 @@ a t
explain select count(*) from t1 as tt1, (select * from t1) as tt2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY tt1 index NULL a 4 NULL 10000 Using index
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 10000
drop table t1;
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
@@ -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 NULL NULL NULL 6 Using where; Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
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 NULL NULL NULL 6 Using where; Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
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;
@@ -250,7 +250,7 @@ a a
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
-1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 2
5 UNION t1 ALL NULL NULL NULL NULL 2
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
@@ -317,7 +317,7 @@ explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
2 DERIVED x ALL NULL NULL NULL NULL 17 Using temporary; Using filesort
-2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer
+2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
drop table t1;
create table t2 (a int, b int, primary key (a));
insert into t2 values (1,7),(2,7);
diff --git a/mysql-test/suite/pbxt/r/distinct.result b/mysql-test/suite/pbxt/r/distinct.result
index c3e8342a6e1..f821023f03a 100644
--- a/mysql-test/suite/pbxt/r/distinct.result
+++ b/mysql-test/suite/pbxt/r/distinct.result
@@ -173,9 +173,9 @@ INSERT INTO t2 values (1),(2),(3);
INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2');
explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using temporary
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using where; Using temporary
1 SIMPLE t2 ref a a 4 test.t1.a 1 Using index
-1 SIMPLE t3 ref a a 5 test.t1.b 1 Using where; Using index
+1 SIMPLE t3 ref a a 5 test.t1.b 1 Using index
SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
a
1
@@ -190,7 +190,7 @@ insert into t3 select * from t4;
explain select distinct t1.a from t1,t3 where t1.a=t3.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 4 Using index; Using temporary
-1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where; Using index; Distinct
+1 SIMPLE t3 ref a a 5 test.t1.a 1 Using index; Distinct
select distinct t1.a from t1,t3 where t1.a=t3.a;
a
1
@@ -300,11 +300,11 @@ WHERE
AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index id id 4 NULL 2 Using index; Using temporary
-1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer
-1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer
-1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
+1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
+1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
+1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
1 SIMPLE t2_lj ref id id 4 test.j_lj_t2.id 1 Using where; Using index; Distinct
-1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
+1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
1 SIMPLE t3_lj ref id id 4 test.j_lj_t3.id 1 Using where; Using index; Distinct
SELECT DISTINCT
t1.id
@@ -515,7 +515,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1_1 ALL NULL NULL NULL NULL 3 Using temporary
-1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer
+1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer (flat, BNL join)
EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
WHERE t1_1.a = t1_2.a;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/suite/pbxt/r/explain.result b/mysql-test/suite/pbxt/r/explain.result
index a9907aa33fe..cd9b1149c1d 100644
--- a/mysql-test/suite/pbxt/r/explain.result
+++ b/mysql-test/suite/pbxt/r/explain.result
@@ -50,7 +50,7 @@ insert into ÔÁÂ (ËÏÌ0) values (1);
insert into ÔÁÂ (ËÏÌ0) values (2);
explain select ËÏÌ0 from ÔÁÂ where ËÏÌ0=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using where; Using index
+1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using index
drop table ÔÁÂ;
set names latin1;
select 3 into @v1;
diff --git a/mysql-test/suite/pbxt/r/func_group.result b/mysql-test/suite/pbxt/r/func_group.result
index 339defca9b5..dc6ea214084 100644
--- a/mysql-test/suite/pbxt/r/func_group.result
+++ b/mysql-test/suite/pbxt/r/func_group.result
@@ -614,7 +614,7 @@ explain
select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range k1 k1 7 NULL 1 Using where; Using index
-1 SIMPLE t2 range k1 k1 3 NULL 1 Using where; Using index; Using join buffer
+1 SIMPLE t2 range k1 k1 3 NULL 1 Using where; Using index; Using join buffer (flat, BNL join)
explain
select min(a4 - 0.01) from t1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -651,7 +651,7 @@ explain
select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index k2 k2 4 NULL 7 Using where; Using index
-1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer
+1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer (flat, BNL join)
drop table t1, t2;
create table t1 (a char(10));
insert into t1 values ('a'),('b'),('c');
diff --git a/mysql-test/suite/pbxt/r/greedy_optimizer.result b/mysql-test/suite/pbxt/r/greedy_optimizer.result
index 1d3e42b70fb..2fb65d4d824 100644
--- a/mysql-test/suite/pbxt/r/greedy_optimizer.result
+++ b/mysql-test/suite/pbxt/r/greedy_optimizer.result
@@ -121,11 +121,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -133,59 +133,59 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -201,11 +201,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -213,59 +213,59 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 290.146368
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 290.146368
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 290.146368
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -277,11 +277,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -289,60 +289,60 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
@@ -353,11 +353,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -365,59 +365,59 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 290.146368
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 290.146368
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 290.146368
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -433,11 +433,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -445,59 +445,59 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
@@ -509,11 +509,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -521,60 +521,60 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
@@ -585,11 +585,11 @@ select @@optimizer_search_depth;
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
@@ -597,59 +597,59 @@ Last_query_cost 822.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 822.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
Last_query_cost 795.625316
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
-1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
+1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
diff --git a/mysql-test/suite/pbxt/r/group_by.result b/mysql-test/suite/pbxt/r/group_by.result
index c5c9099af0d..c7f87f2dc35 100644
--- a/mysql-test/suite/pbxt/r/group_by.result
+++ b/mysql-test/suite/pbxt/r/group_by.result
@@ -537,11 +537,11 @@ a b
explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary
-1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4);
@@ -856,7 +856,7 @@ explain
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
where t2.b=v1.a GROUP BY t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index b b 2 NULL 10 Using index
+1 SIMPLE t2 index b b 2 NULL 10 Using where; Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 1 test.t2.b 1
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
where t2.b=v1.a GROUP BY t2.b;
diff --git a/mysql-test/suite/pbxt/r/group_min_max.result b/mysql-test/suite/pbxt/r/group_min_max.result
index a591832bc0d..e4ba16ce527 100644
--- a/mysql-test/suite/pbxt/r/group_min_max.result
+++ b/mysql-test/suite/pbxt/r/group_min_max.result
@@ -2257,7 +2257,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index
-2 DEPENDENT SUBQUERY t1 index NULL a 10 NULL 1 Using index
+2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
@@ -2268,7 +2268,7 @@ ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2)
AND t1_outer1.b = t1_outer2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
-1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
+1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
diff --git a/mysql-test/suite/pbxt/r/heap.result b/mysql-test/suite/pbxt/r/heap.result
index 57109f0d4c8..366258882ad 100644
--- a/mysql-test/suite/pbxt/r/heap.result
+++ b/mysql-test/suite/pbxt/r/heap.result
@@ -204,7 +204,7 @@ key a (a)
INSERT INTO t1 VALUES (10), (10), (10);
EXPLAIN SELECT * FROM t1 WHERE a=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 3 Using where
+1 SIMPLE t1 ref a a 5 const 3
SELECT * FROM t1 WHERE a=10;
a
10
diff --git a/mysql-test/suite/pbxt/r/join.result b/mysql-test/suite/pbxt/r/join.result
index a74ee3d3b35..2e49a7f02bf 100644
--- a/mysql-test/suite/pbxt/r/join.result
+++ b/mysql-test/suite/pbxt/r/join.result
@@ -774,7 +774,7 @@ insert into t3 select * from t2 where a < 800;
explain select * from t2,t3 where t2.a < 200 and t2.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a,b a 5 NULL 1 Using where
-1 SIMPLE t3 ref b b 5 test.t2.b 1 Using where
+1 SIMPLE t3 ref b b 5 test.t2.b 1
drop table t1, t2, t3;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -794,8 +794,8 @@ Z
vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv
explain select * from t1, t2 A, t2 B where A.a = t1.a and B.a=A.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 10
-1 SIMPLE A eq_ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
+1 SIMPLE A eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
1 SIMPLE B eq_ref PRIMARY PRIMARY 4 test.A.b 1
show status like '%cost%';
Variable_name Value
diff --git a/mysql-test/suite/pbxt/r/join_nested.result b/mysql-test/suite/pbxt/r/join_nested.result
index 5495ba2a55d..d6c4b9a7322 100644
--- a/mysql-test/suite/pbxt/r/join_nested.result
+++ b/mysql-test/suite/pbxt/r/join_nested.result
@@ -74,7 +74,7 @@ WHERE t3.a=1 OR t3.c IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
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`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
@@ -150,7 +150,7 @@ WHERE t3.a>1 OR t3.c IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t5 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`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
@@ -180,7 +180,7 @@ WHERE (t3.a>1 OR t3.c IS NULL) AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+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
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`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
@@ -229,8 +229,8 @@ t8
ON t7.b=t8.b AND t6.b < 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
-1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
+1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
@@ -544,14 +544,14 @@ t0.b=t1.b AND
(t2.a >= 4 OR t2.c IS NULL);
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
+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
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+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
-1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00
-1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00
+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
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -639,7 +639,7 @@ t0.b=t1.b AND
(t9.a=1);
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
+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
@@ -647,7 +647,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+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`)))
SELECT t9.a,t9.b
@@ -836,9 +836,9 @@ ON t3.a=1 AND t2.b=t4.b
WHERE t1.a <= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
+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
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)
CREATE INDEX idx_b ON t2(b);
@@ -850,11 +850,11 @@ LEFT JOIN
ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
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
-1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 1 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 1 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`)))) where 1
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on((((`test`.`t3`.`a` = 1) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`))) and (`test`.`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
@@ -906,7 +906,7 @@ t0.b=t1.b AND
(t9.a=1);
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
+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
@@ -914,7 +914,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+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`)))
CREATE INDEX idx_b ON t4(b);
@@ -956,17 +956,17 @@ t0.b=t1.b AND
(t9.a=1);
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
+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 t4 ref idx_b idx_b 5 test.t2.b 1 100.00
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t5 ALL idx_b 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 t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+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`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`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`.`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`)))
CREATE INDEX idx_b ON t8(b);
EXPLAIN
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -1005,7 +1005,7 @@ t0.b=t1.b AND
(t9.a=1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 3
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1
@@ -1013,7 +1013,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3
1 SIMPLE t7 ALL NULL NULL NULL NULL 2
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1
-1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
ATTENTION: the above EXPLAIN has several competing QEPs with identical
. costs. To combat the plan change it uses --sorted_result and
. and --replace tricks
@@ -1064,7 +1064,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3
1 SIMPLE t7 ALL NULL NULL NULL NULL 2
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1
-1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
ATTENTION: the above EXPLAIN has several competing QEPs with identical
. costs. To combat the plan change it uses --sorted_result
. and --replace tricks
@@ -1204,13 +1204,13 @@ test.t3 analyze status OK
EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
-1 SIMPLE t3 index c c 5 NULL 6 Using index
+1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
1 SIMPLE t2 ref b b 5 test.t3.c 1 Using index
EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL # Using index
-1 SIMPLE t3 index c c 5 NULL # Using index
-1 SIMPLE t2 ref b b 5 test.t3.c # Using index
+1 SIMPLE t3 index c c 5 NULL # Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c # Using where; Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL 0 0
@@ -1280,8 +1280,8 @@ DELETE FROM t3;
EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL # Using index
-1 SIMPLE t3 index c c 5 NULL # Using index
-1 SIMPLE t2 ref b b 5 test.t3.c # Using index
+1 SIMPLE t3 index c c 5 NULL # Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c # Using where; Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL NULL NULL
@@ -1325,8 +1325,8 @@ c11 c21 c31
EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 0
-1 SIMPLE t3 ALL NULL NULL NULL NULL 0
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL);
INSERT INTO t1 VALUES (23, 2340), (26, 9900);
@@ -1453,7 +1453,7 @@ explain select * from t4 join
t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
-1 SIMPLE t3 ref a a 5 test.t2.b X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t5 ref a a 5 test.t3.b X
1 SIMPLE t4 ref a a 5 test.t3.b X Using where
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
@@ -1461,17 +1461,17 @@ join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X Using where
-1 SIMPLE t4 ref a a 5 test.t3.b X
+1 SIMPLE t4 ref a a 5 test.t3.b X Using where
1 SIMPLE t6 ref a a 5 test.t4.b X
-1 SIMPLE t5 ref a a 5 test.t2.b X
+1 SIMPLE t5 ref a a 5 test.t2.b X Using where
1 SIMPLE t7 ref a a 5 test.t5.b X
explain select * from t2 left join
(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
join t5 on t5.a=t3.b) on t3.a=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
-1 SIMPLE t3 ref a a 5 test.t2.b X
-1 SIMPLE t4 ref a a 5 test.t3.b X
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where
+1 SIMPLE t4 ref a a 5 test.t3.b X Using where
1 SIMPLE t6 ref a a 5 test.t4.b X
1 SIMPLE t5 ref a a 5 test.t3.b X
drop table t0, t1, t2, t3, t4, t5, t6, t7;
@@ -1486,8 +1486,8 @@ explain select * from t1 left join
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 10
-1 SIMPLE t2 ref a a 5 test.t1.a 1
-1 SIMPLE t3 ref a a 5 test.t1.a 1
+1 SIMPLE t2 ref a a 5 test.t1.a 1 Using where
+1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where
drop table t1, t2, t3;
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10));
CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10));
diff --git a/mysql-test/suite/pbxt/r/join_outer.result b/mysql-test/suite/pbxt/r/join_outer.result
index 31813a4f06c..e6ae055d811 100644
--- a/mysql-test/suite/pbxt/r/join_outer.result
+++ b/mysql-test/suite/pbxt/r/join_outer.result
@@ -630,7 +630,7 @@ insert into t2 values (10,1),(20,2),(30,3);
explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index
-1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using index
+1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using where; Using index
select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID
10 1 NULL
@@ -688,8 +688,8 @@ a1 a2 b1 b2 c1 c2
explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
drop table t1, t2, t3;
create table t1 (
a int(11),
@@ -859,14 +859,14 @@ a1 a2
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON a1=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
a1 a2 a3
1 NULL NULL
EXPLAIN SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
a0 a1 a2 a3
@@ -875,7 +875,7 @@ EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index PRIMARY PRIMARY 4 NULL 1 Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a0 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
INSERT INTO t0 VALUES (0);
INSERT INTO t1 VALUES (0);
@@ -886,7 +886,7 @@ EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 const PRIMARY PRIMARY 4 const 1 Using index
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
drop table t1,t2;
create table t1 (a int, b int);
diff --git a/mysql-test/suite/pbxt/r/key_cache.result b/mysql-test/suite/pbxt/r/key_cache.result
index 5ff41bd29d7..703389ac763 100644
--- a/mysql-test/suite/pbxt/r/key_cache.result
+++ b/mysql-test/suite/pbxt/r/key_cache.result
@@ -122,7 +122,7 @@ i
explain select count(*) from t1, t2 where t1.p = t2.i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index
-1 SIMPLE t2 ref k1 k1 5 test.t1.p 1 Using where; Using index
+1 SIMPLE t2 ref k1 k1 5 test.t1.p 1 Using index
select count(*) from t1, t2 where t1.p = t2.i;
count(*)
3
diff --git a/mysql-test/suite/pbxt/r/negation_elimination.result b/mysql-test/suite/pbxt/r/negation_elimination.result
index f3edfccf67e..61889824865 100644
--- a/mysql-test/suite/pbxt/r/negation_elimination.result
+++ b/mysql-test/suite/pbxt/r/negation_elimination.result
@@ -79,7 +79,7 @@ a
19
explain select * from t1 where not(a != 10);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
+1 SIMPLE t1 ref a a 5 const 1 Using index
select * from t1 where not(a != 1);
a
1
diff --git a/mysql-test/suite/pbxt/r/null.result b/mysql-test/suite/pbxt/r/null.result
index 0375933cb9c..f931679c96c 100644
--- a/mysql-test/suite/pbxt/r/null.result
+++ b/mysql-test/suite/pbxt/r/null.result
@@ -170,7 +170,7 @@ insert into t1 select i*2 from t1;
insert into t1 values(null);
explain select * from t1 where i=2 or i is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null i i 5 const # Using where; Using index
+1 SIMPLE t1 ref_or_null i i 5 const # Using index
select count(*) from t1 where i=2 or i is null;
count(*)
10
diff --git a/mysql-test/suite/pbxt/r/null_key.result b/mysql-test/suite/pbxt/r/null_key.result
index 8a440284c53..dca1dde82e9 100644
--- a/mysql-test/suite/pbxt/r/null_key.result
+++ b/mysql-test/suite/pbxt/r/null_key.result
@@ -21,10 +21,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a,b a 9 NULL 3 Using where; Using index
explain select * from t1 where (a is null or a = 7) and b=7;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using where; Using index
+1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using index
explain select * from t1 where (a is null or a = 7) and b=7 order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using where; Using index; Using filesort
+1 SIMPLE t1 ref_or_null a,b a 9 const,const 2 Using index; Using filesort
explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 3 Using where; Using index
@@ -151,7 +151,7 @@ alter table t1 modify b int null;
insert into t1 values (7,null), (8,null), (8,7);
explain select * from t1 where a = 7 and (b=7 or b is null);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 10 const,const 2 Using where; Using index
+1 SIMPLE t1 ref_or_null a,b a 10 const,const 2 Using index
select * from t1 where a = 7 and (b=7 or b is null);
a b
7 7
@@ -166,7 +166,7 @@ a b
NULL 7
explain select * from t1 where (a = 7 or a is null) and (a = 7 or a is null);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a a 5 const 5 Using where; Using index
+1 SIMPLE t1 ref_or_null a a 5 const 5 Using index
select * from t1 where (a = 7 or a is null) and (a = 7 or a is null);
a b
7 NULL
@@ -178,12 +178,12 @@ create table t2 (a int);
insert into t2 values (7),(8);
explain select * from t2 straight_join t1 where t1.a=t2.a and b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t1 ref a,b a 10 test.t2.a,const 2 Using where; Using index
drop index b on t1;
explain select * from t2,t1 where t1.a=t2.a and b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t1 ref a a 10 test.t2.a,const 2 Using where; Using index
select * from t2,t1 where t1.a=t2.a and b is null;
a a b
@@ -191,8 +191,8 @@ a a b
8 8 NULL
explain select * from t2,t1 where t1.a=t2.a and (b= 7 or b is null);
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_or_null a a 10 test.t2.a,const 4 Using where; Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t1 ref_or_null a a 10 test.t2.a,const 4 Using index
select * from t2,t1 where t1.a=t2.a and (b= 7 or b is null);
a a b
7 7 7
@@ -202,7 +202,7 @@ a a b
explain select * from t2,t1 where (t1.a=t2.a or t1.a is null) and b= 7;
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_or_null a a 10 test.t2.a,const 4 Using where; Using index
+1 SIMPLE t1 ref_or_null a a 10 test.t2.a,const 4 Using index
select * from t2,t1 where (t1.a=t2.a or t1.a is null) and b= 7;
a a b
7 7 7
@@ -226,7 +226,7 @@ delete from t1 where a=8;
explain select * from t2,t1 where t1.a=t2.a or t1.a is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 4
-1 SIMPLE t1 ref_or_null a a 5 test.t2.a 4 Using where; Using index
+1 SIMPLE t1 ref_or_null a a 5 test.t2.a 4 Using index
explain select * from t2,t1 where t1.a<=>t2.a or (t1.a is null and t1.b <> 9);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 4
@@ -258,7 +258,7 @@ INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4
INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
explain select id from t1 where uniq_id is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref idx1 idx1 5 const 5 Using where
+1 SIMPLE t1 ref idx1 idx1 5 const 5 Using index condition
explain select id from t1 where uniq_id =1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const idx1 idx1 5 const 1
@@ -407,8 +407,8 @@ EXPLAIN SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 ref idx idx 5 test.t1.a 1
-1 SIMPLE t3 ref idx idx 5 test.t2.b 1 Using index
+1 SIMPLE t2 ref idx idx 5 test.t1.a 1 Using where
+1 SIMPLE t3 ref idx idx 5 test.t2.b 1 Using where; Using index
FLUSH STATUS ;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
diff --git a/mysql-test/suite/pbxt/r/order_by.result b/mysql-test/suite/pbxt/r/order_by.result
index 79ff2d6bb3f..c252086fd54 100644
--- a/mysql-test/suite/pbxt/r/order_by.result
+++ b/mysql-test/suite/pbxt/r/order_by.result
@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using index condition
drop table t1,t2,t3;
CREATE TABLE t1 (
`titre` char(80) NOT NULL default '',
@@ -638,7 +638,7 @@ 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);
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 2 Using where; Using filesort
+1 SIMPLE t1 ref_or_null b b 5 const 2 Using filesort
select * from t1 where b=1 or b is null order by a;
a b
1 1
@@ -647,7 +647,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 2 Using where; Using filesort
+1 SIMPLE t1 ref_or_null b b 5 const 2 Using filesort
select * from t1 where b=2 or b is null order by a;
a b
3 NULL
@@ -897,7 +897,7 @@ t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2)
ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
-1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
SELECT t2.b as c FROM
t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2)
ORDER BY c;
diff --git a/mysql-test/suite/pbxt/r/partition_pruning.result b/mysql-test/suite/pbxt/r/partition_pruning.result
index fc17fe37a36..e5e75c55ffb 100644
--- a/mysql-test/suite/pbxt/r/partition_pruning.result
+++ b/mysql-test/suite/pbxt/r/partition_pruning.result
@@ -533,15 +533,15 @@ Table Op Msg_type Msg_text
test.t2 analyze status OK
explain partitions select * from t2 where b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 5 Using where
+1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 5
explain extended select * from t2 where b = 6;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ref b b 5 const 5 100.00 Using where
+1 SIMPLE t2 ref b b 5 const 5 100.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = 6)
explain partitions select * from t2 where b = 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 5 Using where
+1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 5
explain extended select * from t2 where b in (1,3,5);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 range b b 5 NULL 15 100.00 Using where
diff --git a/mysql-test/suite/pbxt/r/ps_1general.result b/mysql-test/suite/pbxt/r/ps_1general.result
index baa944eebab..c4404cb5cd9 100644
--- a/mysql-test/suite/pbxt/r/ps_1general.result
+++ b/mysql-test/suite/pbxt/r/ps_1general.result
@@ -465,9 +465,9 @@ def key 253 64 7 Y 0 31 8
def key_len 253 4096 1 Y 0 31 8
def ref 253 2048 0 Y 0 31 8
def rows 8 10 1 Y 32928 0 63
-def Extra 253 255 27 N 1 31 8
+def Extra 253 255 48 N 1 31 8
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using index condition; Using MRR; Using filesort
drop table if exists t2;
create table t2 (id smallint, name varchar(20)) ;
prepare stmt1 from ' insert into t2 values(?, ?) ' ;
diff --git a/mysql-test/suite/pbxt/r/range.result b/mysql-test/suite/pbxt/r/range.result
index a8e97d1c725..3974bfaa3f2 100644
--- a/mysql-test/suite/pbxt/r/range.result
+++ b/mysql-test/suite/pbxt/r/range.result
@@ -221,31 +221,31 @@ insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
update t1 set y=x;
explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
explain select count(*) from t1 where x in (1);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref x x 5 const 1 Using where; Using index
+1 SIMPLE t1 ref x x 5 const 1 Using index
explain select count(*) from t1 where x in (1,2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index
@@ -277,7 +277,7 @@ INSERT INTO t1 VALUES
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 2 Using where
+1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where; Using MRR
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
@@ -920,7 +920,7 @@ INSERT INTO t1 VALUES
('A2','2005-12-01 08:00:00',1000);
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
Warnings:
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
diff --git a/mysql-test/suite/pbxt/r/select.result b/mysql-test/suite/pbxt/r/select.result
index c06dd06ea3e..9afbea9199e 100644
--- a/mysql-test/suite/pbxt/r/select.result
+++ b/mysql-test/suite/pbxt/r/select.result
@@ -1397,15 +1397,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
@@ -1421,15 +1421,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1437,7 +1437,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
@@ -2369,7 +2369,7 @@ insert into t2 values (1,3), (2,3), (3,4), (4,4);
explain select * from t1 left join t2 on a=c where d in (4);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref c,d d 5 const 1 Using where
-1 SIMPLE t1 ref a a 5 test.t2.c 1 Using where
+1 SIMPLE t1 ref a a 5 test.t2.c 1
select * from t1 left join t2 on a=c where d in (4);
a b c d
3 2 3 4
@@ -2377,7 +2377,7 @@ a b c d
explain select * from t1 left join t2 on a=c where d = 4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref c,d d 5 const 1 Using where
-1 SIMPLE t1 ref a a 5 test.t2.c 1 Using where
+1 SIMPLE t1 ref a a 5 test.t2.c 1
select * from t1 left join t2 on a=c where d = 4;
a b c d
3 2 3 4
@@ -2403,11 +2403,11 @@ 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
-1 SIMPLE t2 ref a a 23 test.t1.a 1
+1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE 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
-1 SIMPLE t2 ref a a 23 test.t1.a 1
+1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where
DROP TABLE t1, t2;
CREATE TABLE t1 ( city char(30) );
INSERT INTO t1 VALUES ('London');
@@ -2722,8 +2722,8 @@ explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
t2.b like '%%' order by t2.b limit 0,1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort
-1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
+1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
+1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a int, INDEX idx(a));
@@ -2746,7 +2746,7 @@ Note 1031 Table storage engine for 't1' doesn't have this option
EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b b 5 NULL 2 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
a b a b
1 NULL 1 1
@@ -2756,7 +2756,7 @@ a b a b
EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b b 5 NULL 2 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
a b a b
1 NULL 1 1
@@ -2910,11 +2910,11 @@ a
EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 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
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON 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 3
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
DROP TABLE t1,t2;
select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
@@ -3466,12 +3466,12 @@ EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 1 Using where
-1 SIMPLE t2 ref c c 5 test.t1.a 1 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 1
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b PRIMARY 4 NULL 1 Using where
-1 SIMPLE t2 ref c c 5 test.t1.a 1 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 1
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,
@@ -3531,7 +3531,7 @@ WHERE t1.id=2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
1 SIMPLE t2 const idx1 NULL NULL NULL 1
-1 SIMPLE t3 ref idx1 idx1 5 const 1 Using where
+1 SIMPLE t3 ref idx1 idx1 5 const 1
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
WHERE t1.id=2;
id a b c d e
@@ -3630,7 +3630,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
+1 SIMPLE t2 range si,ai ai 5 NULL 1 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
DROP TABLE t1,t2,t3;
DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/suite/pbxt/r/select_safe.result b/mysql-test/suite/pbxt/r/select_safe.result
index 8739a89eafb..4d078e96cc2 100644
--- a/mysql-test/suite/pbxt/r/select_safe.result
+++ b/mysql-test/suite/pbxt/r/select_safe.result
@@ -71,13 +71,13 @@ 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");
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
-1 SIMPLE t2 ref b b 21 test.t1.b 1 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 21 Using where
+1 SIMPLE t2 ref b b 21 test.t1.b 1
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
-1 SIMPLE t2 ref b b 21 test.t1.b 1 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 21 Using where
+1 SIMPLE t2 ref b b 21 test.t1.b 1
SET MAX_SEEKS_FOR_KEY=DEFAULT;
drop table t1, t2;
create table t1 (a int);
diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result
index ebe74e442a2..589c864f71b 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 (select 1 AS `a`) `b` having ((select '1') = 1)
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><'1'>((select '1')) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -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;
@@ -719,7 +719,7 @@ id
1
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ref id id 5 const 1 100.00 Using where; Using index
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
Warnings:
Note 1249 Select 2 was reduced during optimization
Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
@@ -731,7 +731,7 @@ id
2
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ref id id 5 const 1 100.00 Using where; Using index
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
Warnings:
Note 1249 Select 3 was reduced during optimization
Note 1249 Select 2 was reduced during optimization
@@ -743,7 +743,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);
@@ -876,6 +876,8 @@ select (select a+1) from t1;
4.5
NULL
drop table t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
CREATE TABLE t2 (a int(11) default '0', INDEX (a));
INSERT INTO t1 VALUES (1),(2),(3),(4);
@@ -891,7 +893,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;
@@ -903,10 +905,10 @@ a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
-2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 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 1 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 1 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);
@@ -1293,31 +1295,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
-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 1 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));
@@ -1332,31 +1334,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; 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 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 (<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`)
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 where; 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; 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 1 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
@@ -1369,10 +1371,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);
@@ -1463,25 +1465,25 @@ 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 t3 (a int);
@@ -1736,14 +1738,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');
@@ -1771,6 +1773,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
create table t1 (a int);
insert into t1 values (1);
explain select benchmark(1000, (select a from t1 where a=sha(rand())));
@@ -2279,7 +2282,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);
@@ -2750,6 +2753,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=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');
@@ -2820,20 +2825,22 @@ 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`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
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 subselect2 eq_ref unique_key unique_key 10 func 1 1.00
+2 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` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary; Using filesort
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`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
+set @@optimizer_switch=@save_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'));
@@ -3004,6 +3011,8 @@ field1 field2
1 1
1 3
DROP TABLE t1, t2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
CREATE TABLE t1(a int, INDEX (a));
INSERT INTO t1 VALUES (1), (3), (5), (7);
INSERT INTO t1 VALUES (NULL);
@@ -3019,6 +3028,7 @@ a a IN (SELECT a FROM t1)
2 NULL
3 1
DROP TABLE t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
CREATE TABLE t2 AS SELECT
@@ -3412,7 +3422,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
a b
@@ -3423,7 +3433,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
-2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1 Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
DROP TABLE t1;
create table t1( f1 int,f2 int);
insert into t1 values (1,1),(2,2);
@@ -3545,7 +3555,7 @@ WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
ORDER BY t1.t DESC LIMIT 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
-1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index; Using join buffer
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t1 ref PRIMARY PRIMARY 8 test.t2.i1,const 1 Using where; Using index; Using filesort
SELECT * FROM t1,t2
WHERE t1.t = (SELECT t1.t FROM t1
@@ -4213,8 +4223,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 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
+1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using where
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
a b
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
@@ -4223,15 +4233,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 index I1 I1 4 NULL 2 Using where; Using index; LooseScan
+1 PRIMARY t2 ref I2 I2 13 test.t2.a 1 Using where
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 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
+1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using where
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
a b
DROP TABLE t1,t2;
@@ -4275,7 +4285,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));
diff --git a/mysql-test/suite/pbxt/r/union.result b/mysql-test/suite/pbxt/r/union.result
index cfcd17cf0d9..50d4df6e241 100644
--- a/mysql-test/suite/pbxt/r/union.result
+++ b/mysql-test/suite/pbxt/r/union.result
@@ -500,12 +500,12 @@ explain (select * from t1 where a=1 and b=10) union (select straight_join t1.a,t
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 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index
-2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer
+2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
explain (select * from t1 where a=1) union (select * from t1 where b=1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
-2 UNION t1 ref b b 5 const 1 Using where
+2 UNION t1 ref b b 5 const 1
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
drop table t1,t2;
create table t1 ( id int not null auto_increment, primary key (id) ,user_name text );
diff --git a/mysql-test/suite/pbxt/t/lock_multi.test b/mysql-test/suite/pbxt/t/lock_multi.test
index 1104620b6b5..f90e31699c8 100644
--- a/mysql-test/suite/pbxt/t/lock_multi.test
+++ b/mysql-test/suite/pbxt/t/lock_multi.test
@@ -48,7 +48,7 @@ insert t1 select * from t2;
connection locker;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert t1 select * from t2";
+ where state = "Table Lock" and info = "insert t1 select * from t2";
--source include/wait_condition.inc
drop table t2;
connection reader;
@@ -72,7 +72,7 @@ connection locker;
# Sleep a bit till the insert of connection reader is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert t1 select * from t2";
+ where state = "Table Lock" and info = "insert t1 select * from t2";
--source include/wait_condition.inc
drop table t2;
connection reader;
@@ -251,7 +251,7 @@ connection reader;
# Wait till connection writer is blocked
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "alter table t1 auto_increment=0";
+ where state = "Table Lock" and info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
send
alter table t1 auto_increment=0;
@@ -259,7 +259,7 @@ connection locker;
# Wait till connection reader is blocked
let $wait_condition=
select count(*) = 2 from information_schema.processlist
- where state = "Locked" and info = "alter table t1 auto_increment=0";
+ where state = "Table Lock" and info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
unlock tables;
connection writer;
@@ -414,16 +414,16 @@ update t1 set i= 10;
connection reader;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update t1 set i= 10";
+ where state = "Table Lock" and info = "update t1 set i= 10";
--source include/wait_condition.inc
send
select * from t1;
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "select * from t1";
+ where state = "Table Lock" and info = "select * from t1";
--source include/wait_condition.inc
-let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
+let $ID= `select id from information_schema.processlist where state = "Table Lock" and info = "update t1 set i= 10"`;
--replace_result $ID ID
eval kill query $ID;
connection reader;
@@ -557,7 +557,7 @@ connection waiter;
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert into t1 values(1)";
+ where state = "Table Lock" and info = "insert into t1 values(1)";
--source include/wait_condition.inc
let $tlwb= `show status like 'Table_locks_waited'`;
unlock tables;
diff --git a/mysql-test/suite/pbxt/t/subselect.test b/mysql-test/suite/pbxt/t/subselect.test
index 15ccef0e025..19658cb202e 100644
--- a/mysql-test/suite/pbxt/t/subselect.test
+++ b/mysql-test/suite/pbxt/t/subselect.test
@@ -477,6 +477,9 @@ drop table t1;
# Null with keys
#
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
CREATE TABLE t2 (a int(11) default '0', INDEX (a));
INSERT INTO t1 VALUES (1),(2),(3),(4);
@@ -1121,6 +1124,8 @@ select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (i
explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
#
# Static tables & rund() in subqueries
#
@@ -1784,6 +1789,9 @@ drop table t1;
# Bug #11867: queries with ROW(,elems>) IN (SELECT DISTINCT <cols> FROM ...)
#
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=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');
@@ -1811,6 +1819,9 @@ 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=@save_optimizer_switch;
+
+
#
# Bug #12392: where cond with IN predicate for rows and NULL values in table
#
@@ -1972,6 +1983,9 @@ DROP TABLE t1, t2;
# with possible NULL values by index access from the outer query
#
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
CREATE TABLE t1(a int, INDEX (a));
INSERT INTO t1 VALUES (1), (3), (5), (7);
INSERT INTO t1 VALUES (NULL);
@@ -1984,6 +1998,8 @@ SELECT a, a IN (SELECT a FROM t1) FROM t2;
DROP TABLE t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
#
# Bug #11302: getObject() returns a String for a sub-query of type datetime
#
@@ -3096,6 +3112,7 @@ SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
DROP TABLE t1,t2;
+
#
# Bug #32400: Complex SELECT query returns correct result only on some
# occasions
diff --git a/mysql-test/suite/sys_vars/r/concurrent_insert_func.result b/mysql-test/suite/sys_vars/r/concurrent_insert_func.result
index 774775a8287..64a14473216 100644
--- a/mysql-test/suite/sys_vars/r/concurrent_insert_func.result
+++ b/mysql-test/suite/sys_vars/r/concurrent_insert_func.result
@@ -37,9 +37,9 @@ INSERT INTO t1(name) VALUES('Record_7');
connection default;
## show processlist info and state ##
SELECT state,info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE state= "Locked" AND info LIKE "INSERT INTO t1%";
+WHERE state= "Table Lock" AND info LIKE "INSERT INTO t1%";
state info
-Locked INSERT INTO t1(name) VALUES('Record_7')
+Table lock INSERT INTO t1(name) VALUES('Record_7')
## table contents befor UNLOCK ##
SELECT * FROM t1;
name
diff --git a/mysql-test/suite/sys_vars/t/concurrent_insert_func.test b/mysql-test/suite/sys_vars/t/concurrent_insert_func.test
index 1a600ffd7f6..f7bd7bce39a 100644
--- a/mysql-test/suite/sys_vars/t/concurrent_insert_func.test
+++ b/mysql-test/suite/sys_vars/t/concurrent_insert_func.test
@@ -98,12 +98,12 @@ INSERT INTO t1(name) VALUES('Record_7');
connection default;
# wait until INSERT will be locked (low performance)
let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE state= "Locked" AND info LIKE "INSERT INTO t1%";
+ WHERE state= "Table Lock" AND info LIKE "INSERT INTO t1%";
--source include/wait_condition.inc
--echo ## show processlist info and state ##
SELECT state,info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE state= "Locked" AND info LIKE "INSERT INTO t1%";
+WHERE state= "Table Lock" AND info LIKE "INSERT INTO t1%";
--echo ## table contents befor UNLOCK ##
SELECT * FROM t1;
UNLOCK TABLES;
diff --git a/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test b/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test
index 61f7d801a1a..3de8d432d1a 100644
--- a/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test
+++ b/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test
@@ -122,7 +122,7 @@ connection default;
--echo ** Wait till con0 is blocked **
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
- WHERE state = 'Locked' AND info = '$my_select';
+ WHERE state = "Table Lock" AND info = '$my_select';
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -207,7 +207,7 @@ connection default;
--echo ** Wait till con0 is blocked **
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
- WHERE state = 'Locked' AND info = '$my_select';
+ WHERE state = "Table Lock" AND info = '$my_select';
--source include/wait_condition.inc
UNLOCK TABLES;
diff --git a/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test b/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test
index e5ced59d175..baa490986e2 100644
--- a/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test
+++ b/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test
@@ -139,7 +139,7 @@ send SELECT * FROM t1;
connection con0;
--echo wait until table is locked
-let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state= 'Locked';
+let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state= "Table Lock";
--source include/wait_condition.inc
UNLOCK TABLES;
diff --git a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
index 5e0314c25ae..6a4cb2b664c 100644
--- a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
+++ b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
@@ -85,7 +85,7 @@ delimiter ;|
--echo ** Connection con0 **
connection con0;
-let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state='Locked' AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
+let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state="Table Lock" AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
--source include/wait_condition.inc
--echo ** Asynchronous Execution **
@@ -101,7 +101,7 @@ delimiter ;|
--echo ** Connection default **
connection default;
-let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE 'Locked';
+let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE "Table Lock";
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -156,7 +156,7 @@ delimiter ;|
--echo ** Connection con0 **
connection con0;
-let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state='Locked' AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
+let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state="Table Lock" AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
--source include/wait_condition.inc
--echo ** Asynchronous Execution **
@@ -172,7 +172,7 @@ delimiter ;|
--echo ** Connection default **
connection default;
-let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE 'Locked';
+let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE "Table Lock";
--source include/wait_condition.inc
UNLOCK TABLES;
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index e83a89c44c3..91fc6643af4 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -133,3 +133,22 @@ t1 CREATE TABLE `t1` (
`v` char(32) CHARACTER SET ucs2 AS (a) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (3, 30), (4, 20), (1, 20);
+create table t2 (c int, d int, v int as (d+1), index idx(c));
+insert into t2(c,d) values
+(20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
+(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
+set join_cache_level=6;
+explain
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+a b c d v
+4 20 20 100 101
+1 20 20 100 101
+3 30 30 100 101
+set join_cache_level=default;
+drop table t1, t2;
diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result
index f5b430fe233..68a9b2a7a63 100644
--- a/mysql-test/suite/vcol/r/vcol_select_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result
@@ -22,7 +22,7 @@ a b c
1 -1 -1
explain select * from t2 where c=-1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref c c 5 const 1 Using where
+1 SIMPLE t2 ref c c 5 const 1
# select_type=SIMPLE, type=ALL
select * from t1 where b=-1;
a b c
@@ -44,7 +44,7 @@ a b c
1 -1 -1
explain select * from t3 where c>=-1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using MRR
# select_type=SIMPLE, type=ref
select * from t1,t3 where t1.c=t3.c and t3.c=-1;
a b c a b c
@@ -53,7 +53,7 @@ a b c a b c
explain select * from t1,t3 where t1.c=t3.c and t3.c=-1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 const c c 5 const 1
-1 SIMPLE t1 ref c c 5 const 2 Using where
+1 SIMPLE t1 ref c c 5 const 2
# select_type=PRIMARY, type=index,ALL
select * from t1 where b in (select c from t3);
a b c
@@ -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; Using where
+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 ref c c 5 test.t3.c 1
# select_type=UNION, type=system
# select_type=UNION RESULT, type=<union1,2>
select * from t1 union select * from t2;
@@ -137,11 +137,11 @@ id select_type table type possible_keys key key_len ref rows Extra
# SELECT * FROM tbl_name WHERE <vcol expr>
select * from t3 where c >= -2;
a b c
-2 -2 -2
1 -1 -1
+2 -2 -2
explain select * from t3 where c >= -2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using MRR
# SELECT * FROM tbl_name WHERE <non-vcol expr>
select * from t3 where a between 1 and 2;
a b c
@@ -161,11 +161,11 @@ id select_type table type possible_keys key key_len ref rows Extra
# SELECT * FROM tbl_name WHERE <indexed vcol expr>
select * from t3 where c between -2 and -1;
a b c
-2 -2 -2
1 -1 -1
+2 -2 -2
explain select * from t3 where c between -2 and -1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using MRR
# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <non-indexed vcol>
select * from t3 where a between 1 and 2 order by b;
a b c
@@ -205,7 +205,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using MRR; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
select * from t3 where b between -2 and -1 order by c;
a b c
@@ -221,7 +221,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition
# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
select sum(b) from t1 group by b;
sum(b)
diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result
index 45e4defd315..a5d24a32693 100644
--- a/mysql-test/suite/vcol/r/vcol_select_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result
@@ -44,7 +44,7 @@ a b c
1 -1 -1
explain select * from t3 where c>=-1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 2 Using where
+1 SIMPLE t3 range c c 5 NULL 2 Using index condition; Using MRR
# select_type=SIMPLE, type=ref
select * from t1,t3 where t1.c=t3.c and t3.c=-1;
a b c a b c
@@ -53,7 +53,7 @@ a b c a b c
explain select * from t1,t3 where t1.c=t3.c and t3.c=-1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 const c c 5 const 1
-1 SIMPLE t1 ref c c 5 const 2 Using where
+1 SIMPLE t1 ref c c 5 const 2
# select_type=PRIMARY, type=index,ALL
select * from t1 where b in (select c from t3);
a b c
@@ -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; Using where
+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;
@@ -141,15 +141,15 @@ a b c
1 -1 -1
explain select * from t3 where c >= -2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 2 Using where
+1 SIMPLE t3 range c c 5 NULL 2 Using index condition; Using MRR
# SELECT * FROM tbl_name WHERE <non-vcol expr>
select * from t3 where a between 1 and 2;
a b c
-1 -1 -1
2 -2 -2
+1 -1 -1
explain select * from t3 where a between 1 and 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where
+1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using MRR
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr>
select * from t3 where b between -2 and -1;
a b c
@@ -165,7 +165,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using MRR
# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol>
select * from t3 where a between 1 and 2 order by c;
a b c
@@ -173,7 +173,7 @@ a b c
1 -1 -1
explain select * from t3 where a between 1 and 2 order by c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort
+1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where; Using MRR; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol>
select * from t3 where b between -2 and -1 order by a;
a b c
@@ -189,7 +189,7 @@ a b c
2 -2 -2
explain select * from t3 where c between -2 and -1 order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using where; Using MRR; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol>
select * from t3 where b between -2 and -1 order by b;
a b c
@@ -205,7 +205,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Using MRR; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
select * from t3 where b between -2 and -1 order by c;
a b c
@@ -221,7 +221,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using where
+1 SIMPLE t3 range c c 5 NULL 1 Using index condition
# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
select sum(b) from t1 group by b;
sum(b)
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index 2a8d9a576b4..bd868f46111 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -140,3 +140,23 @@ CREATE TABLE t1 (a char(32), v char(32) CHARACTER SET ucs2 AS (a) VIRTUAL);
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+#
+# SELECT that uses a virtual column and executed with BKA
+#
+
+create table t1 (a int, b int);
+insert into t1 values (3, 30), (4, 20), (1, 20);
+create table t2 (c int, d int, v int as (d+1), index idx(c));
+insert into t2(c,d) values
+ (20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
+ (70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
+
+set join_cache_level=6;
+explain
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+set join_cache_level=default;
+
+drop table t1, t2;
diff --git a/mysql-test/t/ctype_cp1251.test b/mysql-test/t/ctype_cp1251.test
index 463a9cea4bc..5e2bc5dc820 100644
--- a/mysql-test/t/ctype_cp1251.test
+++ b/mysql-test/t/ctype_cp1251.test
@@ -44,6 +44,7 @@ insert into t1 (a) values ('air'),
('we_martin'),('vw_grado'),('vw_vasko'),('tn_vili'),('tn_kalina'),
('tn_fakira'),('vw_silvia'),('vw_starshi'),('vw_geo'),('vw_b0x1');
+--sorted_result
select * from t1 where a like 'we_%';
drop table t1;
diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
index 637c6ba1c81..02c09f52263 100644
--- a/mysql-test/t/heap_btree.test
+++ b/mysql-test/t/heap_btree.test
@@ -263,3 +263,19 @@ DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a;
DROP TABLE t1;
--echo End of 5.0 tests
+-- echo # bit index in heap tables
+
+create table t1 (a bit(63) not null) engine=heap;
+insert into t1 values (869751),(736494),(226312),(802616),(728912);
+alter table t1 add unique uniq_id using BTREE (a);
+select 0+a from t1 where a > 736494;
+explain select 0+a from t1 where a > 736494;
+select 0+a from t1 where a = 736494;
+explain select 0+a from t1 where a = 736494;
+select 0+a from t1 where a=869751 or a=736494;
+explain select 0+a from t1 where a=869751 or a=736494;
+select 0+a from t1 where a in (869751,736494,226312,802616);
+explain select 0+a from t1 where a in (869751,736494,226312,802616);
+drop table t1;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/t/heap_hash.test b/mysql-test/t/heap_hash.test
index 1e3491f89a9..a2960560e57 100644
--- a/mysql-test/t/heap_hash.test
+++ b/mysql-test/t/heap_hash.test
@@ -284,3 +284,20 @@ INSERT INTO t1 VALUES('A ', 'A ');
DROP TABLE t1;
--echo End of 5.0 tests
+
+-- echo # bit index in heap tables
+
+create table t1 (a bit(63) not null) engine=heap;
+insert into t1 values (869751),(736494),(226312),(802616),(728912);
+alter table t1 add unique uniq_id using HASH (a);
+select 0+a from t1 where a > 736494;
+explain select 0+a from t1 where a > 736494;
+select 0+a from t1 where a = 736494;
+explain select 0+a from t1 where a = 736494;
+select 0+a from t1 where a=869751 or a=736494;
+explain select 0+a from t1 where a=869751 or a=736494;
+select 0+a from t1 where a in (869751,736494,226312,802616);
+explain select 0+a from t1 where a in (869751,736494,226312,802616);
+drop table t1;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/t/index_merge_myisam.test b/mysql-test/t/index_merge_myisam.test
index 0c4b9c6886c..b3514e3f053 100644
--- a/mysql-test/t/index_merge_myisam.test
+++ b/mysql-test/t/index_merge_myisam.test
@@ -20,78 +20,6 @@ let $merge_table_support= 1;
--source include/index_merge_2sweeps.inc
--source include/index_merge_ror_cpk.inc
---echo #
---echo # Generic @@optimizer_switch tests (move those into a separate file if
---echo # we get another @@optimizer_switch user)
---echo #
-
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='index_merge=off,index_merge_union=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='index_merge_union=on';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,index_merge_sort_union=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch=4;
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch=NULL;
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='default,index_merge';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=index_merge';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=on,but...';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='on';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=on,index_merge=off';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge_union=on,index_merge_union=default';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='default,index_merge=on,index_merge=off,default';
-
-set optimizer_switch=default;
-set optimizer_switch='index_merge=off,index_merge_union=off,default';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-set optimizer_switch=default;
-
-# Check setting defaults for global vars
---replace_regex /,table_elimination=on//
-select @@global.optimizer_switch;
-set @@global.optimizer_switch=default;
---replace_regex /,table_elimination=on//
-select @@global.optimizer_switch;
-
---echo #
---echo # Check index_merge's @@optimizer_switch flags
---echo #
---replace_regex /,table_elimination.on//
-select @@optimizer_switch;
-
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, c int, filler char(100),
@@ -190,8 +118,6 @@ set optimizer_switch='default,index_merge_union=off';
explain select * from t1 where a=10 and b=10 or c=10;
set optimizer_switch=default;
---replace_regex /,table_elimination.on//
-show variables like 'optimizer_switch';
drop table t0, t1;
diff --git a/mysql-test/t/innodb_mrr.test b/mysql-test/t/innodb_mrr.test
new file mode 100644
index 00000000000..70c7c54332e
--- /dev/null
+++ b/mysql-test/t/innodb_mrr.test
@@ -0,0 +1,366 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+--enable_warnings
+
+set @save_storage_engine= @@storage_engine;
+set storage_engine=InnoDB;
+
+--source include/mrr_tests.inc
+
+set storage_engine= @save_storage_engine;
+
+# Try big rowid sizes
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=64;
+
+# By default InnoDB will fill values only for key parts used by the query,
+# which will cause DS-MRR to supply an invalid tuple on scan restoration.
+# Verify that DS-MRR's code extra(HA_EXTRA_RETRIEVE_ALL_COLS) call has effect:
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a char(8), b char(8), c char(8), filler char(100), key(a,b,c) ) engine=InnoDB;
+
+insert into t2 select
+ concat('a-', 1000 + A.a, '-a'),
+ concat('b-', 1000 + B.a, '-b'),
+ concat('c-', 1000 + C.a, '-c'),
+ 'filler'
+from t1 A, t1 B, t1 C;
+
+explain
+select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a';
+select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a';
+drop table t2;
+
+# Try a very big rowid
+create table t2 (a char(100), b char(100), c char(100), d int,
+ filler char(10), key(d), primary key (a,b,c)) engine= innodb;
+insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B;
+--replace_column 9 #
+explain select * from t2 force index (d) where d < 10;
+drop table t2;
+
+drop table t1;
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+
+#
+# BUG#33033 "MySQL/InnoDB crashes with simple select range query"
+#
+create table t1 (f1 int not null, f2 int not null,f3 int not null, f4 char(1), primary key (f1,f2), key ix(f3))Engine=InnoDB;
+
+--disable_query_log
+let $1=55;
+
+while ($1)
+{
+ eval insert into t1(f1,f2,f3,f4) values ($1,$1,$1,'A');
+ dec $1;
+}
+--enable_query_log
+
+# The following must not crash:
+select * from t1 where (f3>=5 and f3<=10) or (f3>=1 and f3<=4);
+
+drop table t1;
+
+--echo
+--echo BUG#37977: Wrong result returned on GROUP BY + OR + Innodb
+--echo
+CREATE TABLE t1 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `int_key` int(11) NOT NULL,
+ `date_key` date NOT NULL,
+ `date_nokey` date NOT NULL,
+ `time_key` time NOT NULL,
+ `time_nokey` time NOT NULL,
+ `datetime_key` datetime NOT NULL,
+ `datetime_nokey` datetime NOT NULL,
+ `varchar_key` varchar(5) DEFAULT NULL,
+ `varchar_nokey` varchar(5) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`),
+ KEY `date_key` (`date_key`),
+ KEY `time_key` (`time_key`),
+ KEY `datetime_key` (`datetime_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+(1,5,5,'2009-10-16','2009-10-16','09:28:15','09:28:15','2007-09-14 05:34:08','2007-09-14 05:34:08','qk','qk'),
+(2,6,6,'0000-00-00','0000-00-00','23:06:39','23:06:39','0000-00-00 00:00:00','0000-00-00 00:00:00','j','j'),
+(3,10,10,'2000-12-18','2000-12-18','22:16:19','22:16:19','2006-11-04 15:42:50','2006-11-04 15:42:50','aew','aew'),
+(4,0,0,'2001-09-18','2001-09-18','00:00:00','00:00:00','2004-03-23 13:23:35','2004-03-23 13:23:35',NULL,NULL),
+(5,6,6,'2007-08-16','2007-08-16','22:13:38','22:13:38','2004-08-19 11:01:28','2004-08-19 11:01:28','qu','qu');
+select pk from t1 WHERE `varchar_key` > 'kr' group by pk;
+select pk from t1 WHERE `int_nokey` IS NULL OR `varchar_key` > 'kr' group by pk;
+drop table t1;
+
+--echo #
+--echo # BUG#39447: Error with NOT NULL condition and LIMIT 1
+--echo #
+CREATE TABLE t1 (
+ id int(11) NOT NULL,
+ parent_id int(11) DEFAULT NULL,
+ name varchar(10) DEFAULT NULL,
+ PRIMARY KEY (id),
+ KEY ind_parent_id (parent_id)
+) ENGINE=InnoDB;
+
+insert into t1 (id, parent_id, name) values
+(10,NULL,'A'),
+(20,10,'B'),
+(30,10,'C'),
+(40,NULL,'D'),
+(50,40,'E'),
+(60,40,'F'),
+(70,NULL,'J');
+
+SELECT id FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
+--echo This must show type=index, extra=Using where
+explain SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
+SELECT * FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
+drop table t1;
+
+
+-- echo #
+-- echo # BUG#628785: multi_range_read.cc:430: int DsMrr_impl::dsmrr_init(): Assertion `do_sort_keys || do_rowid_fetch' failed
+-- echo #
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_switch= @@optimizer_switch;
+SET SESSION join_cache_level=9;
+SET SESSION optimizer_switch='mrr_sort_keys=off';
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,6,NULL,'r','r');
+INSERT INTO `t1` VALUES (2,8,0,'c','c');
+INSERT INTO `t1` VALUES (97,7,0,'z','z');
+INSERT INTO `t1` VALUES (98,1,1,'j','j');
+INSERT INTO `t1` VALUES (99,7,8,'c','c');
+INSERT INTO `t1` VALUES (100,2,5,'f','f');
+SELECT table1 .`col_varchar_key`
+FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ;
+DROP TABLE t1;
+set join_cache_level=@save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # BUG#623300: Query with join_cache_level = 6 returns extra rows in maria-5.3-dsmrr-cpk
+--echo #
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_nokey int(11) DEFAULT NULL,
+ PRIMARY KEY (pk)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (10,7);
+INSERT INTO t1 VALUES (11,1);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (13,3);
+INSERT INTO t1 VALUES (14,6);
+INSERT INTO t1 VALUES (15,92);
+INSERT INTO t1 VALUES (16,7);
+INSERT INTO t1 VALUES (17,NULL);
+INSERT INTO t1 VALUES (18,3);
+INSERT INTO t1 VALUES (19,5);
+INSERT INTO t1 VALUES (20,1);
+INSERT INTO t1 VALUES (21,2);
+INSERT INTO t1 VALUES (22,NULL);
+INSERT INTO t1 VALUES (23,1);
+INSERT INTO t1 VALUES (24,0);
+INSERT INTO t1 VALUES (25,210);
+INSERT INTO t1 VALUES (26,8);
+INSERT INTO t1 VALUES (27,7);
+INSERT INTO t1 VALUES (28,5);
+INSERT INTO t1 VALUES (29,NULL);
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_nokey int(11) DEFAULT NULL,
+ PRIMARY KEY (pk)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,NULL);
+INSERT INTO t2 VALUES (2,7);
+INSERT INTO t2 VALUES (3,9);
+INSERT INTO t2 VALUES (4,7);
+INSERT INTO t2 VALUES (5,4);
+INSERT INTO t2 VALUES (6,2);
+INSERT INTO t2 VALUES (7,6);
+INSERT INTO t2 VALUES (8,8);
+INSERT INTO t2 VALUES (9,NULL);
+INSERT INTO t2 VALUES (10,5);
+INSERT INTO t2 VALUES (11,NULL);
+INSERT INTO t2 VALUES (12,6);
+INSERT INTO t2 VALUES (13,188);
+INSERT INTO t2 VALUES (14,2);
+INSERT INTO t2 VALUES (15,1);
+INSERT INTO t2 VALUES (16,1);
+INSERT INTO t2 VALUES (17,0);
+INSERT INTO t2 VALUES (18,9);
+INSERT INTO t2 VALUES (19,NULL);
+INSERT INTO t2 VALUES (20,4);
+
+set @my_save_join_cache_level= @@join_cache_level;
+SET join_cache_level = 0;
+
+--sorted_result
+SELECT table2.col_int_nokey
+FROM t1 table1 JOIN t2 table2 ON table2.pk = table1.col_int_nokey
+WHERE table1.pk ;
+
+SET join_cache_level = 6;
+
+--sorted_result
+SELECT table2.col_int_nokey
+FROM t1 table1 JOIN t2 table2 ON table2.pk = table1.col_int_nokey
+WHERE table1.pk ;
+
+set join_cache_level= @my_save_join_cache_level;
+drop table t1, t2;
+
+--echo #
+--echo # BUG#623315: Query returns less rows when run with join_cache_level=6 on maria-5.3-dsmrr-cpk
+--echo #
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_nokey int(11) DEFAULT NULL,
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (10,7,8,'v');
+INSERT INTO t1 VALUES (11,1,9,'r');
+INSERT INTO t1 VALUES (12,5,9,'a');
+INSERT INTO t1 VALUES (13,3,186,'m');
+INSERT INTO t1 VALUES (14,6,NULL,'y');
+INSERT INTO t1 VALUES (15,92,2,'j');
+INSERT INTO t1 VALUES (16,7,3,'d');
+INSERT INTO t1 VALUES (17,NULL,0,'z');
+INSERT INTO t1 VALUES (18,3,133,'e');
+INSERT INTO t1 VALUES (19,5,1,'h');
+INSERT INTO t1 VALUES (20,1,8,'b');
+INSERT INTO t1 VALUES (21,2,5,'s');
+INSERT INTO t1 VALUES (22,NULL,5,'e');
+INSERT INTO t1 VALUES (23,1,8,'j');
+INSERT INTO t1 VALUES (24,0,6,'e');
+INSERT INTO t1 VALUES (25,210,51,'f');
+INSERT INTO t1 VALUES (26,8,4,'v');
+INSERT INTO t1 VALUES (27,7,7,'x');
+INSERT INTO t1 VALUES (28,5,6,'m');
+INSERT INTO t1 VALUES (29,NULL,4,'c');
+
+set @my_save_join_cache_level= @@join_cache_level;
+SET join_cache_level=6;
+select count(*) from
+(SELECT table2.pk FROM
+ t1 LEFT JOIN t1 table2 JOIN t1 table3 ON table3.col_varchar_key = table2.col_varchar_key
+ ON table3.col_int_nokey) foo;
+
+SET join_cache_level=0;
+select count(*) from
+(SELECT table2.pk FROM
+ t1 LEFT JOIN t1 table2 JOIN t1 table3 ON table3.col_varchar_key = table2.col_varchar_key
+ ON table3.col_int_nokey) foo;
+
+set join_cache_level= @my_save_join_cache_level;
+drop table t1;
+
+
+--echo #
+--echo # BUG#671340: Diverging results in with mrr_sort_keys=ON|OFF and join_cache_level=5
+--echo #
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) NOT NULL,
+ col_varchar_key varchar(1) NOT NULL,
+ col_varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+ (10,8,'v','v'),
+ (11,8,'f','f'),
+ (12,5,'v','v'),
+ (13,8,'s','s'),
+ (14,8,'a','a'),
+ (15,6,'p','p'),
+ (16,7,'z','z'),
+ (17,2,'a','a'),
+ (18,5,'h','h'),
+ (19,7,'h','h'),
+ (20,2,'v','v'),
+ (21,9,'v','v'),
+ (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');
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) NOT NULL,
+ col_varchar_key varchar(1) NOT NULL,
+ col_varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+ (1,9,'x','x'),
+ (2,5,'g','g'),
+ (3,1,'o','o'),
+ (4,0,'g','g'),
+ (5,1,'v','v'),
+ (6,190,'m','m'),
+ (7,6,'x','x'),
+ (8,3,'c','c'),
+ (9,4,'z','z'),
+ (10,3,'i','i'),
+ (11,186,'x','x'),
+ (12,1,'g','g'),
+ (13,8,'q','q'),
+ (14,226,'m','m'),
+ (15,133,'p','p'),
+ (16,6,'e','e'),
+ (17,3,'t','t'),
+ (18,8,'j','j'),
+ (19,5,'h','h'),
+ (20,7,'w','w');
+
+SELECT count(*), sum(table1.col_int_key*table2.pk)
+FROM
+ t2 AS table1, t1 AS table2, t2 AS table3
+WHERE
+ table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
+
+set @my_save_join_cache_level= @@join_cache_level;
+set @my_save_join_buffer_size= @@join_buffer_size;
+set join_cache_level=6;
+set join_buffer_size=1500;
+
+SELECT count(*), sum(table1.col_int_key*table2.pk)
+FROM
+ t2 AS table1, t1 AS table2, t2 AS table3
+WHERE
+ table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
+
+drop table t1,t2;
+set join_cache_level=@my_save_join_cache_level;
+set join_buffer_size=@my_save_join_buffer_size;
+
diff --git a/mysql-test/t/innodb_mrr_cpk.test b/mysql-test/t/innodb_mrr_cpk.test
new file mode 100644
index 00000000000..69eeef9618f
--- /dev/null
+++ b/mysql-test/t/innodb_mrr_cpk.test
@@ -0,0 +1,137 @@
+#
+# Tests for DS-MRR over clustered primary key. The only engine that supports
+# this is InnoDB/XtraDB.
+#
+# Basic idea about testing
+# - DS-MRR/CPK works only with BKA
+# - Should also test index condition pushdown
+# - Should also test whatever uses RANGE_SEQ_IF::skip_record() for filtering
+# - Also test access using prefix of primary key
+#
+# - Forget about cost model, BKA's multi_range_read_info() call passes 10 for
+# #rows, the call is there at all only for applicability check
+#
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t0,t1,t2,t3;
+--enable_warnings
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+
+set @save_storage_engine=@@storage_engine;
+set storage_engine=innodb;
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a char(8), b char(8), filler char(100), primary key(a));
+show create table t1;
+
+insert into t1 select
+ concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'),
+ concat('b-', 1000 + A.a + B.a*10 + C.a*100, '=B'),
+ 'filler'
+from t0 A, t0 B, t0 C;
+
+create table t2 (a char(8));
+insert into t2 values ('a-1010=A'), ('a-1030=A'), ('a-1020=A');
+
+--echo This should use join buffer:
+explain select * from t1, t2 where t1.a=t2.a;
+
+--echo This output must be sorted by value of t1.a:
+select * from t1, t2 where t1.a=t2.a;
+drop table t1, t2;
+
+# Try multi-column indexes
+create table t1(
+ a char(8) character set utf8, b int, filler char(100),
+ primary key(a,b)
+);
+
+insert into t1 select
+ concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'),
+ 1000 + A.a + B.a*10 + C.a*100,
+ 'filler'
+from t0 A, t0 B, t0 C;
+
+create table t2 (a char(8) character set utf8, b int);
+insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+
+# Try with dataset that causes identical lookup keys:
+insert into t2 values ('a-1030=A', 1030), ('a-1020=A', 1020);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+
+drop table t1, t2;
+
+create table t1(
+ a varchar(8) character set utf8, b int, filler char(100),
+ primary key(a,b)
+);
+
+insert into t1 select
+ concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'),
+ 1000 + A.a + B.a*10 + C.a*100,
+ 'filler'
+from t0 A, t0 B, t0 C;
+
+create table t2 (a char(8) character set utf8, b int);
+insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020);
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+
+#
+# Try scanning on a CPK prefix
+#
+explain select * from t1, t2 where t1.a=t2.a;
+select * from t1, t2 where t1.a=t2.a;
+drop table t1, t2;
+
+#
+# The above example is not very interesting, as CPK prefix has
+# only one match. Create a dataset where scan on CPK prefix
+# would produce multiple matches:
+#
+create table t1 (a int, b int, c int, filler char(100), primary key(a,b,c));
+insert into t1 select A.a, B.a, C.a, 'filler' from t0 A, t0 B, t0 C;
+
+insert into t1 values (11, 11, 11, 'filler');
+insert into t1 values (11, 11, 12, 'filler');
+insert into t1 values (11, 11, 13, 'filler');
+insert into t1 values (11, 22, 1234, 'filler');
+insert into t1 values (11, 33, 124, 'filler');
+insert into t1 values (11, 33, 125, 'filler');
+
+create table t2 (a int, b int);
+insert into t2 values (11,33), (11,22), (11,11);
+
+explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+
+# Check a real resultset for comaprison:
+set join_cache_level=0;
+select * from t1, t2 where t1.a=t2.a and t1.b=t2.b;
+set join_cache_level=6;
+
+
+#
+# Check that Index Condition Pushdown (BKA) actually works:
+#
+explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+
+set optimizer_switch='index_condition_pushdown=off';
+explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
+set optimizer_switch='index_condition_pushdown=on';
+
+drop table t1,t2;
+
+set @@join_cache_level= @save_join_cache_level;
+set storage_engine=@save_storage_engine;
+drop table t0;
+
diff --git a/mysql-test/t/insert_notembedded.test b/mysql-test/t/insert_notembedded.test
index 24040f9c310..baf6a9a28a3 100644
--- a/mysql-test/t/insert_notembedded.test
+++ b/mysql-test/t/insert_notembedded.test
@@ -174,7 +174,7 @@ connection default;
# we must wait till the insert opens and locks the table
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and id = $ID;
+ where state = "Table lock" and id = $ID;
--source include/wait_condition.inc
connect (select,localhost,root,,);
--echo connection: select
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 05d630edfb2..cf431ace24c 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -921,4 +921,23 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+--echo #
+--echo # BUG#47217 Lost optimization caused slowdown & wrong result.
+--echo #
+CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
+CREATE INDEX ix1 ON t1(v);
+CREATE TABLE t2 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
+CREATE INDEX ix2 ON t2(v);
+INSERT INTO t1 VALUES (1,'a'),(2,NULL);
+INSERT INTO t2 VALUES (1,NULL);
+EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v ORDER BY 1;
+EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v;
+INSERT INTO t1 VALUES (3,'b'),(4,NULL),(5,'c'),(6,'cc'),(7,'d'),
+ (8,'dd'),(9,'e'),(10,'ee');
+INSERT INTO t2 VALUES (2,NULL);
+FLUSH STATUS;
+SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1;
+SHOW STATUS LIKE 'Handler_read_%';
+DROP TABLE t1, t2;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
new file mode 100644
index 00000000000..e538422475e
--- /dev/null
+++ b/mysql-test/t/join_cache.test
@@ -0,0 +1,2763 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
+DROP DATABASE IF EXISTS world;
+--enable_warnings
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set names utf8;
+
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema1.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+SELECT COUNT(*) FROM Country;
+SELECT COUNT(*) FROM City;
+SELECT COUNT(*) FROM CountryLanguage;
+
+show variables like 'join_buffer_size';
+
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+set join_cache_level=2;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+set join_cache_level=default;
+
+set join_buffer_size=256;
+show variables like 'join_buffer_size';
+
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+set join_cache_level=2;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+set join_cache_level=default;
+set join_buffer_size=default;
+
+show variables like 'join_buffer_size';
+show variables like 'join_cache_level';
+
+DROP DATABASE world;
+
+
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+show variables like 'join_buffer_size';
+set join_cache_level=3;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+show variables like 'join_buffer_size';
+set join_cache_level=4;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+
+show variables like 'join_buffer_size';
+set join_cache_level=5;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+set join_cache_level=7;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+set join_cache_level=8;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+EXPLAIN
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
+ FROM Country LEFT JOIN CountryLanguage ON
+ (CountryLanguage.Country=Country.Code AND Language='English')
+ WHERE
+ Country.Population > 10000000;
+
+set join_buffer_size=256;
+show variables like 'join_buffer_size';
+
+set join_cache_level=3;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+set join_cache_level=4;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+set join_cache_level=5;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+set join_cache_level=7;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+set join_cache_level=8;
+show variables like 'join_cache_level';
+
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+EXPLAIN
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+SELECT City.Name, Country.Name, CountryLanguage.Language
+ FROM City,Country,CountryLanguage
+ WHERE City.Country=Country.Code AND
+ CountryLanguage.Country=Country.Code AND
+ City.Name LIKE 'L%' AND Country.Population > 3000000 AND
+ CountryLanguage.Percentage > 50;
+
+EXPLAIN
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+SELECT Name FROM City
+ WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
+ City.Population > 100000;
+
+set join_cache_level=default;
+set join_buffer_size=default;
+
+show variables like 'join_buffer_size';
+show variables like 'join_cache_level';
+
+set join_cache_level=1;
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND City.Population > 3000000;
+
+set join_cache_level=8;
+set join_buffer_size=384;
+
+--replace_column 9 #
+EXPLAIN
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND City.Population > 3000000;
+
+--sorted_result
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND City.Population > 3000000;
+
+set join_buffer_size=default;
+
+set join_cache_level=6;
+
+ALTER TABLE Country MODIFY Name varchar(52) NOT NULL default '';
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+ALTER TABLE Country MODIFY Name varchar(300) NOT NULL default '';
+
+SELECT City.Name, Country.Name FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+ALTER TABLE Country ADD COLUMN PopulationBar text;
+UPDATE Country
+ SET PopulationBar=REPEAT('x', CAST(Population/100000 AS unsigned int));
+
+SELECT City.Name, Country.Name, Country.PopulationBar FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+set join_buffer_size=256;
+
+SELECT City.Name, Country.Name, Country.PopulationBar FROM City,Country
+ WHERE City.Country=Country.Code AND
+ Country.Name LIKE 'L%' AND City.Population > 100000;
+
+set join_cache_level=default;
+set join_buffer_size=default;
+
+DROP DATABASE world;
+
+use test;
+
+#
+# Bug #35685: assertion abort when initializing a BKA cache
+#
+
+CREATE TABLE t1(
+ affiliatetometaid int NOT NULL default '0',
+ uniquekey int NOT NULL default '0',
+ metaid int NOT NULL default '0',
+ affiliateid int NOT NULL default '0',
+ xml text,
+ isactive char(1) NOT NULL default 'Y',
+ PRIMARY KEY (affiliatetometaid)
+);
+CREATE UNIQUE INDEX t1_uniquekey ON t1(uniquekey);
+CREATE INDEX t1_affiliateid ON t1(affiliateid);
+CREATE INDEX t1_metaid on t1 (metaid);
+INSERT INTO t1 VALUES
+ (1616, 1571693233, 1391, 2, NULL, 'Y'), (1943, 1993216749, 1726, 2, NULL, 'Y');
+
+CREATE TABLE t2(
+ metaid int NOT NULL default '0',
+ name varchar(80) NOT NULL default '',
+ dateadded timestamp NOT NULL ,
+ xml text,
+ status int default NULL,
+ origin int default NULL,
+ gid int NOT NULL default '1',
+ formattypeid int default NULL,
+ PRIMARY KEY (metaid)
+);
+CREATE INDEX t2_status ON t2(status);
+CREATE INDEX t2_gid ON t2(gid);
+CREATE INDEX t2_formattypeid ON t2(formattypeid);
+INSERT INTO t2 VALUES
+ (1391, "I Just Died", "2003-10-02 10:07:37", "", 1, NULL, 3, NULL),
+ (1726, "Me, Myself & I", "2003-12-05 11:24:36", " ", 1, NULL, 3, NULL);
+
+CREATE TABLE t3(
+ mediaid int NOT NULL ,
+ metaid int NOT NULL default '0',
+ formatid int NOT NULL default '0',
+ status int default NULL,
+ path varchar(100) NOT NULL default '',
+ datemodified timestamp NOT NULL ,
+ resourcetype int NOT NULL default '1',
+ parameters text,
+ signature int default NULL,
+ quality int NOT NULL default '255',
+ PRIMARY KEY (mediaid)
+);
+CREATE INDEX t3_metaid ON t3(metaid);
+CREATE INDEX t3_formatid ON t3(formatid);
+CREATE INDEX t3_status ON t3(status);
+CREATE INDEX t3_metaidformatid ON t3(metaid,formatid);
+CREATE INDEX t3_signature ON t3(signature);
+CREATE INDEX t3_quality ON t3(quality);
+INSERT INTO t3 VALUES
+ (6, 4, 8, 0, "010101_anastacia_spmidi.mid", "2004-03-16 13:40:00", 1, NULL, NULL, 255),
+ (3343, 3, 8, 1, "010102_4VN4bsPwnxRQUJW5Zp1RhG2IL9vvl_8.mid", "2004-03-16 13:40:00", 1, NULL, NULL, 255);
+
+CREATE TABLE t4(
+ formatid int NOT NULL ,
+ name varchar(60) NOT NULL default '',
+ formatclassid int NOT NULL default '0',
+ mime varchar(60) default NULL,
+ extension varchar(10) default NULL,
+ priority int NOT NULL default '0',
+ canaddtocapability char(1) NOT NULL default 'Y',
+ PRIMARY KEY (formatid)
+);
+CREATE INDEX t4_formatclassid ON t4(formatclassid);
+CREATE INDEX t4_formats_idx ON t4(canaddtocapability);
+INSERT INTO t4 VALUES
+ (19, "XHTML", 11, "text/html", "xhtml", 10, 'Y'),
+ (54, "AMR (wide band)", 13, "audio/amr-wb", "awb", 0, 'Y');
+
+CREATE TABLE t5(
+ formatclassid int NOT NULL ,
+ name varchar(60) NOT NULL default '',
+ priority int NOT NULL default '0',
+ formattypeid int NOT NULL default '0',
+ PRIMARY KEY (formatclassid)
+);
+CREATE INDEX t5_formattypeid on t5(formattypeid);
+INSERT INTO t5 VALUES
+ (11, "Info", 0, 4), (13, "Digital Audio", 0, 2);
+
+CREATE TABLE t6(
+ formattypeid int NOT NULL ,
+ name varchar(60) NOT NULL default '',
+ priority int default NULL,
+ PRIMARY KEY (formattypeid)
+);
+INSERT INTO t6 VALUES
+ (2, "Ringtones", 0);
+
+CREATE TABLE t7(
+ metaid int NOT NULL default '0',
+ artistid int NOT NULL default '0',
+ PRIMARY KEY (metaid,artistid)
+);
+INSERT INTO t7 VALUES
+ (4, 5), (3, 4);
+
+CREATE TABLE t8(
+ artistid int NOT NULL ,
+ name varchar(80) NOT NULL default '',
+ PRIMARY KEY (artistid)
+);
+INSERT INTO t8 VALUES
+ (5, "Anastacia"), (4, "John Mayer");
+
+CREATE TABLE t9(
+ subgenreid int NOT NULL default '0',
+ metaid int NOT NULL default '0',
+ PRIMARY KEY (subgenreid,metaid)
+) ;
+CREATE INDEX t9_subgenreid ON t9(subgenreid);
+CREATE INDEX t9_metaid ON t9(metaid);
+INSERT INTO t9 VALUES
+ (138, 4), (31, 3);
+
+CREATE TABLE t10(
+ subgenreid int NOT NULL ,
+ genreid int NOT NULL default '0',
+ name varchar(80) NOT NULL default '',
+ PRIMARY KEY (subgenreid)
+) ;
+CREATE INDEX t10_genreid ON t10(genreid);
+INSERT INTO t10 VALUES
+ (138, 19, ''), (31, 3, '');
+
+CREATE TABLE t11(
+ genreid int NOT NULL default '0',
+ name char(80) NOT NULL default '',
+ priority int NOT NULL default '0',
+ masterclip char(1) default NULL,
+ PRIMARY KEY (genreid)
+) ;
+CREATE INDEX t11_masterclip ON t11( masterclip);
+INSERT INTO t11 VALUES
+ (19, "Pop & Dance", 95, 'Y'), (3, "Rock & Alternative", 100, 'Y');
+
+set join_cache_level=6;
+
+EXPLAIN
+SELECT t1.uniquekey, t1.xml AS affiliateXml,
+ t8.name AS artistName, t8.artistid,
+ t11.name AS genreName, t11.genreid, t11.priority AS genrePriority,
+ t10.subgenreid, t10.name AS subgenreName,
+ t2.name AS metaName, t2.metaid, t2.xml AS metaXml,
+ t4.priority + t5.priority + t6.priority AS overallPriority,
+ t3.path AS path, t3.mediaid,
+ t4.formatid, t4.name AS formatName,
+ t5.formatclassid, t5.name AS formatclassName,
+ t6.formattypeid, t6.name AS formattypeName
+FROM t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
+WHERE t7.metaid = t2.metaid AND t7.artistid = t8.artistid AND
+ t9.metaid = t2.metaid AND t9.subgenreid = t10.subgenreid AND
+ t10.genreid = t11.genreid AND t3.metaid = t2.metaid AND
+ t3.formatid = t4.formatid AND t4.formatclassid = t5.formatclassid AND
+ t4.canaddtocapability = 'Y' AND t5.formattypeid = t6.formattypeid AND
+ t6.formattypeid IN (2) AND (t3.formatid IN (31, 8, 76)) AND
+ t1.metaid = t2.metaid AND t1.affiliateid = '2';
+
+SELECT t1.uniquekey, t1.xml AS affiliateXml,
+ t8.name AS artistName, t8.artistid,
+ t11.name AS genreName, t11.genreid, t11.priority AS genrePriority,
+ t10.subgenreid, t10.name AS subgenreName,
+ t2.name AS metaName, t2.metaid, t2.xml AS metaXml,
+ t4.priority + t5.priority + t6.priority AS overallPriority,
+ t3.path AS path, t3.mediaid,
+ t4.formatid, t4.name AS formatName,
+ t5.formatclassid, t5.name AS formatclassName,
+ t6.formattypeid, t6.name AS formattypeName
+FROM t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
+WHERE t7.metaid = t2.metaid AND t7.artistid = t8.artistid AND
+ t9.metaid = t2.metaid AND t9.subgenreid = t10.subgenreid AND
+ t10.genreid = t11.genreid AND t3.metaid = t2.metaid AND
+ t3.formatid = t4.formatid AND t4.formatclassid = t5.formatclassid AND
+ t4.canaddtocapability = 'Y' AND t5.formattypeid = t6.formattypeid AND
+ t6.formattypeid IN (2) AND (t3.formatid IN (31, 8, 76)) AND
+ t1.metaid = t2.metaid AND t1.affiliateid = '2';
+
+DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
+
+#
+# Bug #37131: 3-way join query with BKA used with a small buffer and
+# only for the third table
+#
+
+CREATE TABLE t1 (a1 int, filler1 char(64) default ' ' );
+CREATE TABLE t2 (
+ a2 int, b2 int, filler2 char(64) default ' ',
+ PRIMARY KEY idx(a2,b2,filler2)
+) ;
+CREATE TABLE t3 (b3 int, c3 int, INDEX idx(b3));
+
+INSERT INTO t1(a1) VALUES
+ (4), (7), (1), (9), (8), (5), (3), (6), (2);
+INSERT INTO t2(a2,b2) VALUES
+ (1,30), (3,40), (2,61), (6,73), (8,92), (9,27), (4,18), (5,84), (7,56),
+ (4,14), (6,76), (8,98), (7,55), (1,39), (2,68), (3,45), (9,21), (5,81),
+ (5,88), (2,65), (6,74), (9,23), (1,37), (3,44), (4,17), (8,99), (7,51),
+ (9,28), (7,52), (1,33), (4,13), (5,87), (3,43), (8,91), (2,62), (6,79),
+ (3,49), (8,93), (7,34), (5,82), (6,78), (2,63), (1,32), (9,22), (4,11);
+INSERT INTO t3 VALUES
+ (30,302), (92,923), (18,187), (45,459), (30,309),
+ (39,393), (68,685), (45,458), (21,210), (81,817),
+ (40,405), (61,618), (73,738), (92,929), (27,275),
+ (18,188), (84,846), (56,564), (14,144), (76,763),
+ (98,982), (55,551), (17,174), (99,998), (51,513),
+ (28,282), (52,527), (33,336), (13,138), (87,878),
+ (43,431), (91,916), (62,624), (79,797), (49,494),
+ (93,933), (34,347), (82,829), (78,780), (63,634),
+ (32,329), (22,228), (11,114), (74,749), (23,236);
+
+set join_cache_level=1;
+
+EXPLAIN
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+ SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+ SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+
+set join_cache_level=5;
+set join_buffer_size=512;
+
+EXPLAIN
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+ SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+
+SELECT a1<>a2, a1, a2, b2, b3, c3,
+ SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
+FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
+
+DROP TABLE t1,t2,t3;
+
+#
+# Bug #37690: crash with a tiny buffer when using BKA_JOIN_CACHE_UNIQUE
+#
+
+CREATE TABLE t1 (a int, b int, INDEX idx(b));
+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);
+
+set join_buffer_size=32;
+set join_cache_level=8;
+
+EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30;
+--sorted_result
+SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #40134: outer join with not exists optimization and join buffer
+--echo #
+
+set join_cache_level=default;
+set join_buffer_size=default;
+
+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);
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+
+SET join_cache_level=6;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+
+DROP TABLE t1, t2;
+
+set join_cache_level=default;
+set join_buffer_size=default;
+
+--echo #
+--echo # BUG#40136: Group by is ignored when join buffer is used for an outer join
+--echo #
+create table t1(a int PRIMARY KEY, b int);
+insert into t1 values
+ (5, 10), (2, 70), (7, 80), (6, 20), (1, 50), (9, 40), (8, 30), (3, 60);
+create table t2 (p int, a int, INDEX i_a(a));
+insert into t2 values
+ (103, 7), (109, 3), (102, 3), (108, 1), (106, 3),
+ (107, 7), (105, 1), (101, 3), (100, 7), (110, 1);
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+--echo The following must not show "using join cache":
+explain
+select t1.a, count(t2.p) as count
+ from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
+select t1.a, count(t2.p) as count
+ from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
+set join_cache_level=@save_join_cache_level;
+drop table t1, t2;
+
+--echo #
+--echo # BUG#40268: Nested outer join with not null-rejecting where condition
+--echo # over an inner table which is not the last in the nest
+--echo #
+
+CREATE TABLE t2 (a int, b int, c int);
+CREATE TABLE t3 (a int, b int, c int);
+CREATE TABLE t4 (a int, b int, c int);
+
+INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0);
+INSERT INTO t3 VALUES (1,2,0), (2,2,0);
+INSERT INTO t4 VALUES (3,2,0), (4,2,0);
+
+set join_cache_level=6;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2 LEFT JOIN (t3, t4) ON t2.b=t4.b
+ WHERE t3.a+2<t2.a OR t3.c IS NULL;
+
+set join_cache_level=default;
+DROP TABLE t2, t3, t4;
+
+--echo #
+--echo # Bug #40192: outer join with where clause when using BNL
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (2, 20), (3, 30), (1, 10);
+create table t2 (a int, c int);
+insert into t2 values (1, 101), (3, 102), (1, 100);
+
+set join_cache_level=6;
+
+select * from t1 left join t2 on t1.a=t2.a;
+explain select * from t1 left join t2 on t1.a=t2.a where t2.c=102 or t2.c is null;
+select * from t1 left join t2 on t1.a=t2.a where t2.c=102 or t2.c is null;
+
+set join_cache_level=default;
+drop table t1, t2;
+
+--echo #
+--echo # Bug #40317: outer join with with constant on expression equal to FALSE
+--echo #
+
+create table t1 (a int);
+insert into t1 values (30), (40), (20);
+create table t2 (b int);
+insert into t2 values (200), (100);
+
+set join_cache_level=6;
+
+select * from t1 left join t2 on (1=0);
+explain select * from t1 left join t2 on (1=0) where a=40;
+select * from t1 left join t2 on (1=0) where a=40;
+
+set join_cache_level=0;
+explain select * from t1 left join t2 on (1=0);
+
+set join_cache_level=default;
+drop table t1, t2;
+
+--echo #
+--echo # Bug #41204: small buffer with big rec_per_key for ref access
+--echo #
+
+CREATE TABLE t1 (a int);
+
+INSERT INTO t1 VALUES (0);
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1 VALUES (20000), (10000);
+
+CREATE TABLE t2 (pk int AUTO_INCREMENT PRIMARY KEY, b int, c int, INDEX idx(b));
+INSERT INTO t2(b,c) VALUES (10000, 3), (20000, 7), (20000, 1), (10000, 9), (20000, 5);
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+INSERT INTO t2(b,c) SELECT b,c FROM t2;
+
+--disable_result_log
+ANALYZE TABLE t1,t2;
+--enable_result_log
+
+set join_cache_level=6;
+set join_buffer_size=1024;
+
+EXPLAIN SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b;
+SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b;
+
+set join_buffer_size=default;
+set join_cache_level=default;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #41894: big join buffer of level 7 used to join records
+--echo # with null values in place of varchar strings
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ b varchar(127) DEFAULT NULL);
+
+INSERT INTO t1(a) VALUES (1);
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+INSERT INTO t1(b) SELECT b FROM t1;
+
+CREATE TABLE t2 (a int NOT NULL PRIMARY KEY, b varchar(127) DEFAULT NULL);
+INSERT INTO t2 SELECT * FROM t1;
+
+CREATE TABLE t3 (a int NOT NULL PRIMARY KEY, b varchar(127) DEFAULT NULL);
+INSERT INTO t3 SELECT * FROM t1;
+
+set join_cache_level=7;
+set join_buffer_size=1024*1024;
+
+EXPLAIN
+SELECT COUNT(*) FROM t1,t2,t3
+ WHERE t1.a=t2.a AND t2.a=t3.a AND
+ t1.b IS NULL AND t2.b IS NULL AND t3.b IS NULL;
+
+SELECT COUNT(*) FROM t1,t2,t3
+ WHERE t1.a=t2.a AND t2.a=t3.a AND
+ t1.b IS NULL AND t2.b IS NULL AND t3.b IS NULL;
+
+set join_buffer_size=default;
+set join_cache_level=default;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #42020: join buffer is used for outer join with fields of
+--echo # several outer tables in join buffer
+--echo #
+
+CREATE TABLE t1 (
+ a bigint NOT NULL,
+ PRIMARY KEY (a)
+);
+INSERT INTO t1 VALUES
+ (2), (1);
+
+CREATE TABLE t2 (
+ a bigint NOT NULL,
+ b bigint NOT NULL,
+ PRIMARY KEY (a,b)
+);
+INSERT INTO t2 VALUES
+ (2,30), (2,40), (2,50), (2,60), (2,70), (2,80),
+ (1,10), (1, 20), (1,30), (1,40), (1,50);
+
+CREATE TABLE t3 (
+ pk bigint NOT NULL AUTO_INCREMENT,
+ a bigint NOT NULL,
+ b bigint NOT NULL,
+ val bigint DEFAULT '0',
+ PRIMARY KEY (pk),
+ KEY idx (a,b)
+);
+INSERT INTO t3(a,b) VALUES
+ (2,30), (2,40), (2,50), (2,60), (2,70), (2,80),
+ (4,30), (4,40), (4,50), (4,60), (4,70), (4,80),
+ (5,30), (5,40), (5,50), (5,60), (5,70), (5,80),
+ (7,30), (7,40), (7,50), (7,60), (7,70), (7,80);
+
+set join_cache_level=0;
+
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+ FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+ WHERE t1.a=t2.a;
+
+set join_cache_level=6;
+set join_buffer_size=256;
+
+EXPLAIN
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+ FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+ WHERE t1.a=t2.a;
+--sorted_result
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+ FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+ WHERE t1.a=t2.a;
+
+DROP INDEX idx ON t3;
+set join_cache_level=2;
+
+EXPLAIN
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+ FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+ WHERE t1.a=t2.a;
+
+--sorted_result
+SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
+ FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
+ WHERE t1.a=t2.a;
+
+set join_buffer_size=default;
+set join_cache_level=default;
+
+DROP TABLE t1,t2,t3;
+
+#
+# WL#4424 Full index condition pushdown with batched key access join
+#
+create table t1(f1 int, f2 int);
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2(f1 int not null, f2 int not null, f3 char(200), key(f1,f2));
+insert into t2 values (1,1, 'qwerty'),(1,2, 'qwerty'),(1,3, 'qwerty');
+insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'),
+ (2,4, 'qwerty'),(2,5, 'qwerty');
+insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty');
+insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'),
+ (4,4, 'qwerty');
+insert into t2 values (1,1, 'qwerty'),(1,2, 'qwerty'),(1,3, 'qwerty');
+insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'),
+ (2,4, 'qwerty'),(2,5, 'qwerty');
+insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty');
+insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'),
+ (4,4, 'qwerty');
+
+set join_cache_level=5;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+
+set join_cache_level=6;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+
+set join_cache_level=7;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+
+set join_cache_level=8;
+select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
+
+explain select t2.f1, t2.f2, t2.f3 from t1,t2
+where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
+
+drop table t1,t2;
+set join_cache_level=default;
+
+--echo #
+--echo # Bug #42955: join with GROUP BY/ORDER BY and when BKA is enabled
+--echo #
+
+create table t1 (d int, id1 int, index idx1 (d, id1));
+insert into t1 values
+ (3, 20), (2, 40), (3, 10), (1, 10), (3, 20), (1, 40), (2, 30), (3, 30);
+
+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);
+
+set join_cache_level=6;
+
+explain
+select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
+ where t1.d=3 group by t1.id1;
+
+select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
+ where t1.d=3 group by t1.id1;
+
+explain
+select t1.id1 from t1 join t2 on t1.id1=t2.id1
+ where t1.d=3 and t2.id2 > 200 order by t1.id1;
+
+select t1.id1 from t1 join t2 on t1.id1=t2.id1
+ where t1.d=3 and t2.id2 > 200 order by t1.id1;
+
+set join_cache_level=default;
+
+drop table t1,t2;
+
+--echo #
+--echo # Bug #44019: star-like multi-join query executed join_cache_level=6
+--echo #
+
+create table t1 (a int, b int, c int, d int);
+create table t2 (b int, e varchar(16), index idx(b));
+create table t3 (d int, f varchar(16), index idx(d));
+create table t4 (c int, g varchar(16), index idx(c));
+
+insert into t1 values
+ (5, 50, 500, 5000), (3, 30, 300, 3000), (9, 90, 900, 9000),
+ (2, 20, 200, 2000), (4, 40, 400, 4000), (8, 80, 800, 800),
+ (7, 70, 700, 7000);
+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 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 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');
+
+--disable_result_log
+--disable_warnings
+analyze table t2,t3,t4;
+--enable_warnings
+--enable_result_log
+
+set join_cache_level=1;
+explain
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+ where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+ where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+
+set join_cache_level=6;
+explain
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+ where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+
+select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
+ where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
+
+set join_cache_level=default;
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #44250: Corruption of linked join buffers when using BKA
+--echo #
+
+CREATE TABLE t1 (
+ id1 bigint(20) DEFAULT NULL,
+ id2 bigint(20) DEFAULT NULL,
+ id3 bigint(20) DEFAULT NULL,
+ num1 bigint(20) DEFAULT NULL,
+ num2 int(11) DEFAULT NULL,
+ num3 bigint(20) DEFAULT NULL
+);
+
+CREATE TABLE t2 (
+ id3 bigint(20) NOT NULL DEFAULT '0',
+ id4 bigint(20) DEFAULT NULL,
+ enum1 enum('Enabled','Disabled','Paused') DEFAULT NULL,
+ PRIMARY KEY (id3)
+);
+
+CREATE TABLE t3 (
+ id4 bigint(20) NOT NULL DEFAULT '0',
+ text1 text,
+ PRIMARY KEY (id4)
+);
+
+CREATE TABLE t4 (
+ id2 bigint(20) NOT NULL DEFAULT '0',
+ dummy int(11) DEFAULT '0',
+ PRIMARY KEY (id2)
+);
+
+CREATE TABLE t5 (
+ id1 bigint(20) NOT NULL DEFAULT '0',
+ id2 bigint(20) NOT NULL DEFAULT '0',
+ enum2 enum('Active','Deleted','Paused') DEFAULT NULL,
+ PRIMARY KEY (id1,id2)
+);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+
+INSERT INTO t1 VALUES
+(228172702,72485641,2667134182,10,1,14),(228172702,94266195,2667134182,134,0,134),
+(228172702,94266195,2667134182,15,0,15),(228172702,94266195,2667134182,2,0,3),
+(228172702,818095880,2667134182,1,1,1),(228172702,1004959639,2667134182,3,0,3),
+(228172702,1297484422,2667134182,1,2,1),(228172702,1730911800,2667134182,11,0,28),
+(228172702,1730911800,2667134182,4,0,4),(228172702,2182755982,2667134182,5,0,15),
+(228172702,2182755982,2667134182,1,0,1),(228172702,2968841184,2667134182,1,0,1),
+(228172702,4765525626,2667134182,2,0,3),(228172702,4765525626,2667134182,29,0,38),
+(228172702,4765525626,2667134182,7,0,7),(228172702,4765525626,2667134182,7,0,8),
+(228172702,5330573302,2667134182,1,0,1),(228512602,191149872,935692942,3,0,17),
+(228512602,259118753,935692942,13,7,13),(228512602,259118753,935692942,83,33,83),
+(228512602,585705465,935692942,1,0,1),(228512602,585716775,935692942,1,0,1),
+(228512602,585716775,935692942,6,6,6),(228512602,585716775,935692942,1,1,1),
+(228512602,1105371172,935692942,2,0,3),(228512602,1105371172,935692942,7,2,7),
+(228512602,1314223462,935692942,1,0,1),(228512602,1314223642,935692942,1,1,1),
+(228512602,1411060522,935692942,1,0,1),(228512602,1467398182,935692942,1,0,1),
+(228512602,1467398182,935692942,3,0,4),(228512602,1467398242,935692942,10,0,41),
+(228512602,1467398242,935692942,28,0,40),(228512602,1467398242,935692942,0,0,0),
+(228512602,1467398242,935692942,29,2,33),(228512602,1734178942,935692942,1,0,1),
+(228512602,1734179122,935692942,1,0,4),(228512602,1734179122,935692942,3,0,6),
+(228512602,1953612870,935692942,1,0,1),(228512602,2271510562,935692942,1,1,1),
+(228512602,2271525022,935692942,0,0,0),(228512602,3058831402,935692942,1,1,1),
+(228512602,3723638842,935692942,1,1,1),(228512602,3723638842,935692942,4,3,4),
+(228512602,3723836602,935692942,1,1,1),(228512602,3723836842,935692942,1,1,1),
+(228512602,3723836962,935692942,1,1,1),(228512602,3723988102,935692942,11,4,11),
+(228512602,3723989182,935692942,8,3,8),(228512602,5920283002,935692942,1,0,1),
+(228512602,5920314232,935692942,1,0,1),(228512602,191149872,1241589892,0,0,0),
+(228512602,191149872,1241589892,2,0,4),(228512602,191149872,1241589892,0,0,0),
+(228512602,259118753,1241589892,8,4,8),(228512602,259118753,1241589892,70,33,70),
+(228512602,259118753,1241589892,1,1,1),(228512602,585716775,1241589892,8,7,8),
+(228512602,1105371172,1241589892,1,0,1),(228512602,1105371172,1241589892,9,0,9),
+(228512602,1314223462,1241589892,1,0,1),(228512602,1411060522,1241589892,1,1,1),
+(228512602,1467398182,1241589892,1,0,1),(228512602,1467398182,1241589892,4,1,4),
+(228512602,1467398182,1241589892,1,0,1),(228512602,1467398242,1241589892,10,0,28),
+(228512602,1467398242,1241589892,37,1,78),(228512602,1467398242,1241589892,28,9,30),
+(228512602,1467398242,1241589892,5,0,6),(228512602,1734179122,1241589892,3,1,18),
+(228512602,1734179122,1241589892,1,1,1),(228512602,1734179122,1241589892,2,0,3),
+(228512602,1953611430,1241589892,1,1,1),(228512602,1953611430,1241589892,1,1,1),
+(228512602,1953612870,1241589892,1,0,1),(228512602,2026844250,1241589892,1,0,1),
+(228512602,2271510562,1241589892,1,1,1),(228512602,2271525022,1241589892,1,0,1),
+(228512602,2941612417,1241589892,1,0,1),(228512602,3723988102,1241589892,1,0,1);
+INSERT INTO t1 VALUES
+(228512602,3723988102,1241589892,11,4,11),(228512602,3723989002,1241589892,1,0,1),
+(228512602,3752960902,1241589892,2,2,4),(228808822,17304242,935693782,6,0,17),
+(228808822,17304242,935693782,28,1,50),(228808822,17304242,935693782,29,3,61),
+(228808822,17304242,935693782,6,0,13),(228808822,30931012,935693782,21,0,60),
+(228808822,30931012,935693782,5,0,13),(228808822,37254452,935693782,3,0,3),
+(228808822,42726891,935693782,1,0,4),(228808822,42726891,935693782,3,0,6),
+(228808822,76261151,935693782,8,0,18),(228808822,88240139,935693782,1,0,1),
+(228808822,88240139,935693782,3,0,3),(228808822,94730895,935693782,2,0,4),
+(228808822,179737402,935693782,10,0,13),(228808822,179737402,935693782,7,0,8),
+(228808822,179737402,935693782,3,0,4),(228808822,271288782,935693782,1,0,6),
+(228808822,304690943,935693782,5,2,10),(228808822,304691183,935693782,4,0,16),
+(228808822,568994960,935693782,1,0,1),(228808822,631705925,935693782,1,0,1),
+(228808822,631745165,935693782,1,0,1),(228808822,631749605,935693782,1,0,4),
+(228808822,1057787002,935693782,1,0,1),(228808822,1057787002,935693782,2,1,4),
+(228808822,1057787002,935693782,12,1,20),(228808822,1057788022,935693782,2,0,40),
+(228808822,1057788022,935693782,2,1,3),(228808822,1057788022,935693782,9,2,16),
+(228808822,1335646822,935693782,3,1,6),(228808822,1335646882,935693782,1,0,3),
+(228808822,1335646882,935693782,1,0,3),(228808822,1335646942,935693782,7,2,15),
+(228808822,5510586183,935693782,1,1,1),(228808822,17304242,2482416112,11,0,28),
+(228808822,17304242,2482416112,34,0,62),(228808822,17304242,2482416112,43,2,89),
+(228808822,17304242,2482416112,9,0,19),(228808822,30931012,2482416112,32,2,84),
+(228808822,30931012,2482416112,6,0,14),(228808822,30931012,2482416112,2,0,9),
+(228808822,37254452,2482416112,1,1,1),(228808822,42726891,2482416112,2,0,10),
+(228808822,76261151,2482416112,11,0,26),(228808822,88240139,2482416112,3,0,3),
+(228808822,88240139,2482416112,1,0,1),(228808822,88240139,2482416112,3,0,4),
+(228808822,94730895,2482416112,1,0,3),(228808822,125469602,2482416112,0,0,0),
+(228808822,179737402,2482416112,4,0,10),(228808822,179737402,2482416112,8,1,9),
+(228808822,179737402,2482416112,7,1,9),(228808822,179737402,2482416112,1,0,1),
+(228808822,271288782,2482416112,2,0,14),(228808822,304690943,2482416112,3,0,6),
+(228808822,304691183,2482416112,1,0,4),(228808822,555689643,2482416112,2,1,8),
+(228808822,555689643,2482416112,1,0,4),(228808822,631705925,2482416112,1,0,1),
+(228808822,631712555,2482416112,1,0,1),(228808822,631745165,2482416112,1,0,1),
+(228808822,710348755,2482416112,1,0,1),(228808822,753718113,2482416112,1,0,1),
+(228808822,1057787002,2482416112,1,0,4),(228808822,1057787002,2482416112,1,0,1),
+(228808822,1057787002,2482416112,4,1,7),(228808822,1057788022,2482416112,7,0,12),
+(228808822,1057788022,2482416112,3,0,37),(228808822,1057788022,2482416112,0,0,0),
+(228808822,1057788022,2482416112,12,0,15),(228808822,1335646822,2482416112,14,1,28),
+(228808822,1335646882,2482416112,1,1,3),(228808822,1335646942,2482416112,5,1,9),
+(228808822,1335646942,2482416112,1,0,1),(230941762,16069490,2691187582,0,0,0),
+(230941762,16705991,2691187582,16,0,30),(230941762,16705991,2691187582,12,3,12);
+INSERT INTO t1 VALUES
+(230941762,16705991,2691187582,1,0,1),(230941762,27714032,2691187582,6,0,16),
+(230941762,27714032,2691187582,1,0,1),(230941762,27714032,2691187582,9,0,14),
+(230941762,28676710,2691187582,3,1,4),(230941762,370319272,2691187582,7,0,7),
+(230941762,1409814802,2691187582,1,0,3),(230941762,1409814982,2691187582,1,0,1),
+(230941762,1409814982,2691187582,1,1,1),(230941762,2069703256,2691187582,1,0,3),
+(230941762,16705991,2691187672,8,1,20),(230941762,16705991,2691187672,11,6,11),
+(230941762,16705991,2691187672,1,0,1),(230941762,27714032,2691187672,5,0,20),
+(230941762,27714032,2691187672,1,0,10),(230941762,27714032,2691187672,12,2,17),
+(230941762,28676710,2691187672,1,0,1),(230941762,142889951,2691187672,2,0,10),
+(230941762,172526592,2691187672,1,1,1),(230941762,293109282,2691187672,1,0,1),
+(230941762,370319272,2691187672,10,0,10),(230941762,1409814802,2691187672,1,0,3),
+(230941762,1409814922,2691187672,1,0,1),(230941762,1409814982,2691187672,1,0,1),
+(230941762,16069490,2694472582,1,1,1),(230941762,16069490,2694472582,1,1,1),
+(230941762,16705991,2694472582,15,0,45),(230941762,16705991,2694472582,13,2,15),
+(230941762,27714032,2694472582,9,0,34),(230941762,27714032,2694472582,2,0,4),
+(230941762,27714032,2694472582,10,2,14),(230941762,28676710,2694472582,4,0,12),
+(230941762,28676710,2694472582,1,0,1),(230941762,172526592,2694472582,1,0,4),
+(230941762,293109282,2694472582,1,0,1),(230941762,370319272,2694472582,6,0,6),
+(230941762,1409814802,2694472582,1,0,3),(230941762,1409814862,2694472582,1,0,4),
+(230941762,1409814982,2694472582,1,0,1),(230941762,2680867980,2694472582,1,0,3),
+(230942122,25451690,935695702,1,0,9),(230942122,31549341,935695702,2,0,18),
+(230942122,31549341,935695702,2,0,4),(230942122,38900150,935695702,4,0,29),
+(230942122,38900150,935695702,4,1,13),(230942122,906919252,935695702,39,0,271),
+(230942122,906919252,935695702,20,0,83),(230942122,906919252,935695702,2,1,9),
+(230942122,1409816782,935695702,3,0,18),(230942122,1409816842,935695702,1,0,7),
+(230942122,1409816842,935695702,1,0,3),(230942122,1409816902,935695702,1,0,6),
+(230942122,2145075862,935695702,4,1,4),(230942122,25451690,935695822,2,0,16),
+(230942122,38900150,935695822,3,0,26),(230942122,38900150,935695822,1,0,3),
+(230942122,906919252,935695822,24,0,176),(230942122,906919252,935695822,20,0,74),
+(230942122,906919252,935695822,1,0,3),(230942122,1409816782,935695822,2,0,21),
+(230942122,1409816782,935695822,2,0,21),(230942122,1409816842,935695822,1,0,3),
+(230942122,1409816902,935695822,1,0,7),(231112162,1413675742,935696902,1,0,1),
+(231112162,1413675742,935696962,0,0,0),(231112162,1413675742,935696962,4,2,4),
+(231112162,1413675922,935696962,1,0,1),(231112162,1413675922,935696962,1,0,1),
+(231112162,1413675742,1248588922,1,0,1),(231112162,1413675922,1248588922,3,0,3),
+(233937022,12641121,935697562,2,0,13),(233937022,12653871,935697562,1,0,1),
+(233937022,12693551,935697562,1,0,1),(233937022,12910461,935697562,2,0,6),
+(233937022,12910461,935697562,26,0,65),(233937022,12910461,935697562,44,8,45),
+(233937022,12910481,935697562,12,0,19),(233937022,12910481,935697562,7,2,9),
+(233937022,12910481,935697562,1,0,1),(233937022,12910511,935697562,8,0,8);
+INSERT INTO t1 VALUES
+(233937022,12910511,935697562,20,6,22),(233937022,30879781,935697562,34,0,34),
+(233937022,30879781,935697562,3,0,4),(233937022,30879781,935697562,1,0,1),
+(233937022,45631730,935697562,8,0,39),(233937022,54079090,935697562,12,0,12),
+(233937022,54079090,935697562,7,0,11),(233937022,54079090,935697562,14,0,16),
+(233937022,94431735,935697562,6,0,31),(233937022,96876131,935697562,3,0,4),
+(233937022,105436492,935697562,4,0,4),(233937022,128981555,935697562,3,0,3),
+(233937022,145211004,935697562,1,0,1),(233937022,146382622,935697562,1,0,1),
+(233937022,175678702,935697562,1,0,4),(233937022,298998998,935697562,1,0,1),
+(233937022,335995773,935697562,3,0,3),(233937022,335995773,935697562,2,0,3),
+(233937022,347447636,935697562,0,0,0),(233937022,459295955,935697562,3,0,3),
+(233937022,459376625,935697562,1,0,1),(233937022,495877773,935697562,1,0,1),
+(233937022,497008702,935697562,1,0,3),(233937022,561944105,935697562,1,0,1),
+(233937022,561944105,935697562,1,0,1),(233937022,586535965,935697562,3,0,3),
+(233937022,631549775,935697562,1,0,7),(233937022,647138479,935697562,1,0,1),
+(233937022,655870453,935697562,4,0,7),(233937022,694832725,935697562,1,0,1),
+(233937022,864475057,935697562,1,0,1),(233937022,1010757503,935697562,1,0,4),
+(233937022,1010847736,935697562,2,0,9),(233937022,1287437116,935697562,2,0,4),
+(233937022,1337693056,935697562,1,0,1),(233937022,1569279742,935697562,1,1,1),
+(233937022,1569280102,935697562,2,0,7),(233937022,1569280882,935697562,2,1,3),
+(233937022,1569281062,935697562,1,0,1),(233937022,1569281962,935697562,1,0,3),
+(233937022,2823580588,935697562,2,0,8),(233937022,2823580588,935697562,3,1,10),
+(233937022,2842066134,935697562,1,0,1),(233937022,2904542181,935697562,1,0,1),
+(233937022,3058483627,935697562,1,0,1),(233937022,4507287318,935697562,1,0,1),
+(233937022,5283489892,935697562,1,0,1),(233937022,11890554322,935697562,16,0,16),
+(233937022,11890756102,935697562,3,1,3),(233937022,12641121,953996482,1,0,7),
+(233937022,12641851,953996482,1,0,1),(233937022,12641851,953996482,1,0,1),
+(233937022,12910461,953996482,4,0,14),(233937022,12910461,953996482,20,2,23),
+(233937022,12910461,953996482,43,5,43),(233937022,12910461,953996482,1,0,1),
+(233937022,12910481,953996482,17,2,30),(233937022,12910511,953996482,7,1,8),
+(233937022,12910511,953996482,23,5,23),(233937022,14913951,953996482,2,0,3),
+(233937022,21835210,953996482,1,1,1),(233937022,26481052,953996482,1,1,1),
+(233937022,26481052,953996482,1,0,1),(233937022,30879781,953996482,2,0,3),
+(233937022,30879781,953996482,22,0,22),(233937022,35617681,953996482,1,0,1),
+(233937022,45631730,953996482,3,0,11),(233937022,54079090,953996482,13,0,13),
+(233937022,54079090,953996482,11,0,16),(233937022,54079090,953996482,29,0,34),
+(233937022,94431735,953996482,3,0,9),(233937022,96876131,953996482,3,0,4),
+(233937022,105436492,953996482,1,0,1),(233937022,105437952,953996482,3,1,3),
+(233937022,123639716,953996482,1,0,6),(233937022,145211004,953996482,2,0,3),
+(233937022,145211004,953996482,2,1,3),(233937022,146382622,953996482,1,0,1),
+(233937022,146382622,953996482,1,0,1),(233937022,155454324,953996482,1,0,1);
+INSERT INTO t1 VALUES
+(233937022,298998998,953996482,1,1,1),(233937022,335995773,953996482,1,0,1),
+(233937022,335995773,953996482,7,2,9),(233937022,459295955,953996482,2,0,4),
+(233937022,561944105,953996482,1,0,1),(233937022,655870453,953996482,5,0,9),
+(233937022,694832725,953996482,1,0,1),(233937022,694832725,953996482,1,0,1),
+(233937022,864475057,953996482,4,1,4),(233937022,897886118,953996482,1,0,1),
+(233937022,897886118,953996482,1,0,3),(233937022,1005147016,953996482,1,0,1),
+(233937022,1010757503,953996482,1,0,1),(233937022,1082217873,953996482,1,0,1),
+(233937022,1286925326,953996482,1,0,1),(233937022,1337693056,953996482,4,0,4),
+(233937022,1407236408,953996482,2,0,3),(233937022,1569280102,953996482,1,0,6),
+(233937022,1569280222,953996482,1,0,1),(233937022,1569281062,953996482,1,0,1),
+(233937022,1569284362,953996482,1,0,3),(233937022,2823580588,953996482,1,0,3),
+(233937022,2904542181,953996482,3,0,7),(233937022,4371581485,953996482,1,0,1),
+(233937022,5283491332,953996482,1,0,1),(233937022,7300486013,953996482,1,1,1),
+(233937022,11890554322,953996482,16,0,16),(233937022,11890754392,953996482,1,0,1),
+(233937022,11890754392,953996482,0,0,0);
+
+INSERT INTO t2 VALUES
+(2667134182,2567095402,'Enabled'),(935692942,826927822,'Enabled'),
+(1241589892,1130891152,'Enabled'),(935693782,826928662,'Enabled'),
+(2482416112,2381969632,'Enabled'),(2691187582,2591198842,'Enabled'),
+(2691187672,2591198932,'Enabled'),(2694472582,2594492212,'Paused'),
+(935695702,826930582,'Enabled'),(935695822,826930702,'Enabled'),
+(935696902,826931782,'Enabled'),(935696962,826931842,'Enabled'),
+(1248588922,1137805582,'Enabled'),(935697562,826932442,'Paused'),
+(953996482,845181202,'Enabled'),(2702549092,2602579882,'Enabled'),
+(2702549182,2602579972,'Enabled'),(2702550712,2602581502,'Enabled'),
+(1125312412,1015179502,'Enabled'),(2708245462,2608290202,'Enabled'),
+(2708247262,2608292002,'Enabled'),(935699242,826934122,'Enabled'),
+(1125312502,1015179592,'Enabled'),(1125312592,1015179682,'Enabled'),
+(2711450452,2611502302,'Enabled'),(2711452252,2611504102,'Enabled'),
+(935699902,826934782,'Enabled'),(935700262,826935142,'Enabled'),
+(1215381442,1104677032,'Enabled'),(2503848082,2403457762,'Enabled'),
+(935701762,826936642,'Enabled'),(935701822,826936702,'Enabled'),
+(1468810282,1355227402,'Enabled'),(935702842,826937722,'Enabled'),
+(1125312682,1015179772,'Enabled'),(2713816102,2613869392,'Enabled'),
+(2688452032,2588455012,'Enabled'),(2688452212,2588455192,'Enabled'),
+(2701527412,2601556942,'Enabled'),(1623918712,1510242412,'Enabled'),
+(2701521922,2601551452,'Enabled'),(2701527772,2601557302,'Enabled');
+
+INSERT INTO `t3` VALUES
+(2567095402,'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'),
+(826927822,'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'),(1130891152,'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'),
+(826928662,'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'),
+(2381969632,'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'),
+(2591198842,'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'),
+(2591198932,'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE'),
+(2594492212,'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'),
+(826930582,'GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG'),
+(826930702,'GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG'),
+(826931782,'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'),
+(826931842,'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'),
+(1137805582,'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB');
+
+INSERT INTO t4 VALUES
+(12618121,0),(12641121,0),(12641851,0),(12653871,0),(12665801,0),(12666811,0),
+(12693551,0),(12910461,0),(12910481,0),(12910511,0),(14787251,0),(14913941,0),
+(14913951,0),(16069490,0),(16705901,0),(16705991,0),(17291062,0),(17304242,0),
+(20737411,0),(21524370,0),(21835210,0),(25300361,0),(25451690,0),(25728842,0),
+(26481052,0),(27714032,0),(28676710,0),(30879781,0),(30931012,0),(31549341,0),
+(35617681,0),(37254452,0),(38619430,0),(38895490,0),(38900150,0),(39798990,0),
+(42726891,0),(42867050,0),(43439030,0),(45631730,0),(47171711,0),(49539832,0),
+(54079090,0),(60442241,0),(65320501,0),(72485641,0),(76261151,0),(87949714,0),
+(88240139,0),(94266195,0),(94431735,0),(94730895,0),(96876131,0);
+
+INSERT INTO t5 VALUES
+(228172702,72485641,'Active'),(228172702,94266195,'Active'),
+(228172702,818095880,'Active'),(228172702,1004959639,'Active'),
+(228172702,1297484242,'Active'),(228172702,1297484422,'Active'),
+(228172702,1730911800,'Active'),(228172702,1808277389,'Active'),
+(228172702,2182755982,'Active'),(228172702,2968841184,'Active'),
+(228172702,3015116542,'Active'),(228172702,3752383170,'Active'),
+(228172702,4765525626,'Active'),(228172702,5330573302,'Active'),
+(228512602,191149872,'Active'),(228512602,259118753,'Active'),
+(228512602,585705465,'Active'),(228512602,585716775,'Active'),
+(228512602,1105371172,'Active'),(228512602,1314223462,'Active'),
+(228512602,1314223642,'Active'),(228512602,1411060522,'Active'),
+(228512602,1467398182,'Active'),(228512602,1467398242,'Active'),
+(228512602,1734178942,'Active'),(228512602,1734179122,'Active'),
+(228512602,1953612870,'Active'),(228512602,2271510562,'Active'),
+(228512602,2271525022,'Active'),(228512602,2941612417,'Active'),
+(228512602,3058831402,'Active'),(228512602,3723638842,'Active'),
+(228512602,3723836602,'Active'),(228512602,3723836842,'Active'),
+(228512602,3723836962,'Active'),(228512602,3723988102,'Active'),
+(228512602,3723989182,'Active'),(228512602,5920283002,'Active'),
+(228512602,5920314232,'Active'),(228512602,585717615,'Active'),
+(228512602,1953611430,'Active'),(228512602,2026844250,'Active'),
+(228512602,3058831462,'Active'),(228512602,3723836902,'Active'),
+(228512602,3723989002,'Active'),(228512602,3752960902,'Active'),
+(228808822,17304242,'Active'),(228808822,30931012,'Active'),
+(228808822,37254452,'Active'),(228808822,42726891,'Active'),
+(228808822,76261151,'Active'),(228808822,88240139,'Active'),
+(228808822,94730895,'Active'),(228808822,125469622,'Active'),
+(228808822,179737402,'Active'),(228808822,271288782,'Active'),
+(228808822,304690943,'Active'),(228808822,304691183,'Active'),
+(228808822,496123368,'Active'),(228808822,555689643,'Active'),
+(228808822,568994960,'Active'),(228808822,631705925,'Active'),
+(228808822,631745165,'Active'),(228808822,631749605,'Active'),
+(228808822,1057787002,'Active'),(228808822,1057788022,'Active'),
+(228808822,1335646822,'Active'),(228808822,1335646882,'Active'),
+(228808822,1335646942,'Active'),(228808822,1612792238,'Active'),
+(228808822,5510586183,'Active'),(228808822,47171711,'Active'),
+(228808822,125469602,'Active'),(228808822,631712555,'Active'),
+(228808822,710348755,'Active'),(228808822,753718113,'Active'),
+(230941762,16069490,'Active'),(230941762,16705991,'Active'),
+(230941762,27714032,'Active'),(230941762,28676710,'Active');
+INSERT INTO t5 VALUES
+(230941762,370319272,'Active'),(230941762,1409814802,'Active'),
+(230941762,1409814982,'Active'),(230941762,2069703256,'Active'),
+(230941762,142889951,'Active'),(230941762,172526592,'Active'),
+(230941762,293109282,'Active'),(230941762,1409814922,'Active'),
+(230941762,1409814862,'Active'),(230941762,2680867980,'Active'),
+(230942122,25451690,'Active'),(230942122,31549341,'Active'),
+(230942122,38900150,'Active'),(230942122,464554745,'Active'),
+(230942122,906919252,'Active'),(230942122,1409816782,'Active'),
+(230942122,1409816842,'Active'),(230942122,1409816902,'Active'),
+(230942122,2145075862,'Active'),(231112162,1413675742,'Active'),
+(231112162,1413675922,'Active'),(231112162,1413675562,'Active'),
+(231112162,1413675802,'Active'),(233937022,12641121,'Active'),
+(233937022,12653871,'Active'),(233937022,12693551,'Active'),
+(233937022,12910461,'Active'),(233937022,12910481,'Active'),
+(233937022,12910511,'Active'),(233937022,14913941,'Active'),
+(233937022,30879781,'Active'),(233937022,45631730,'Active'),
+(233937022,54079090,'Active'),(233937022,65320501,'Active'),
+(233937022,94431735,'Active'),(233937022,96876131,'Active'),
+(233937022,105436492,'Active'),(233937022,105437952,'Active'),
+(233937022,128981555,'Active'),(233937022,145211004,'Active'),
+(233937022,146382622,'Active'),(233937022,148832422,'Active'),
+(233937022,175678702,'Active'),(233937022,260507673,'Active'),
+(233937022,298998998,'Active'),(233937022,335995773,'Active'),
+(233937022,347447636,'Active'),(233937022,459295955,'Active'),
+(233937022,459376625,'Active'),(233937022,495877773,'Active'),
+(233937022,497008702,'Active'),(233937022,561944105,'Active'),
+(233937022,586535965,'Active'),(233937022,631549775,'Active'),
+(233937022,647138479,'Active'),(233937022,655870453,'Active'),
+(233937022,694832725,'Active'),(233937022,835712045,'Active'),
+(233937022,864475057,'Active'),(233937022,864484777,'Active'),
+(233937022,1010757503,'Active'),(233937022,1010847736,'Active'),
+(233937022,1091554836,'Active'),(233937022,1287437116,'Active'),
+(233937022,1337693056,'Active'),(233937022,1569279742,'Active'),
+(233937022,1569280102,'Active'),(233937022,1569280222,'Active'),
+(233937022,1569280582,'Active'),(233937022,1569280882,'Active'),
+(233937022,1569281062,'Active'),(233937022,1569281962,'Active'),
+(233937022,1569284362,'Active'),(233937022,1743317015,'Active'),
+(233937022,2698799002,'Active'),(233937022,2698800742,'Active'),
+(233937022,2823580588,'Active'),(233937022,2842066134,'Active'),
+(233937022,2904542181,'Active'),(233937022,3058483627,'Active');
+INSERT INTO t5 VALUES
+(233937022,4507287318,'Active'),(233937022,5283489892,'Active'),
+(233937022,11890554322,'Active'),(233937022,11890756102,'Active'),
+(233937022,12641851,'Active'),(233937022,14913951,'Active'),
+(233937022,21835210,'Active'),(233937022,26481052,'Active'),
+(233937022,35617681,'Active'),(233937022,123639716,'Active'),
+(233937022,155454324,'Active'),(233937022,299001668,'Active'),
+(233937022,897886118,'Active'),(233937022,1005147016,'Active'),
+(233937022,1082217873,'Active'),(233937022,1286925326,'Active'),
+(233937022,1407236408,'Active'),(233937022,4371581485,'Active'),
+(233937022,5283491332,'Active'),(233937022,7300486013,'Active'),
+(233937022,11890754392,'Active');
+
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+set join_cache_level=8;
+set join_buffer_size=2048;
+
+EXPLAIN
+SELECT STRAIGHT_JOIN t1.id1, t1.num3, t3.text1, t3.id4, t2.id3, t4.dummy
+ FROM t1 JOIN t2 JOIN t3 JOIN t4 JOIN t5
+ WHERE t1.id1=t5.id1 AND t1.id2=t5.id2 and t4.id2=t1.id2 AND
+ t5.enum2='Active' AND t3.id4=t2.id4 AND t2.id3=t1.id3 AND t3.text1<'D';
+
+SELECT STRAIGHT_JOIN t1.id1, t1.num3, t3.text1, t3.id4, t2.id3, t4.dummy
+ FROM t1 JOIN t2 JOIN t3 JOIN t4 JOIN t5
+ WHERE t1.id1=t5.id1 AND t1.id2=t5.id2 and t4.id2=t1.id2 AND
+ t5.enum2='Active' AND t3.id4=t2.id4 AND t2.id3=t1.id3 AND t3.text1<'D';
+
+set join_buffer_size=default;
+set join_cache_level=default;
+
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # Bug#45267: Incomplete check caused wrong result.
+--echo #
+CREATE TABLE t1 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
+);
+CREATE TABLE t3 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
+);
+INSERT INTO t3 VALUES
+(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),
+(16),(17),(18),(19),(20);
+CREATE TABLE t2 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_nokey` int(11) NOT NULL,
+ `time_key` time NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `time_key` (`time_key`)
+);
+INSERT INTO t2 VALUES (10,9,'22:36:46'),(11,0,'08:46:46');
+
+SELECT DISTINCT t1.`pk`
+FROM t1 RIGHT JOIN t2 STRAIGHT_JOIN t3 ON t2.`int_nokey` ON t2.`time_key`
+GROUP BY 1;
+
+DROP TABLE IF EXISTS t1, t2, t3;
+
+--echo #
+--echo # Bug #46328: Use of aggregate function without GROUP BY clause
+--echo # returns many rows (vs. one )
+--echo #
+
+CREATE TABLE t1 (
+ int_key int(11) NOT NULL,
+ KEY int_key (int_key)
+);
+
+INSERT INTO t1 VALUES
+(0),(2),(2),(2),(3),(4),(5),(5),(6),(6),(8),(8),(9),(9);
+
+CREATE TABLE t2 (
+ int_key int(11) NOT NULL,
+ KEY int_key (int_key)
+);
+
+INSERT INTO t2 VALUES (2),(3);
+
+--echo
+
+--echo # The query shall return 1 record with a max value 9 and one of the
+--echo # int_key values inserted above (undefined which one). A changed
+--echo # execution plan may change the value in the second column
+SELECT MAX(t1.int_key), t1.int_key
+FROM t1 STRAIGHT_JOIN t2
+ORDER BY t1.int_key;
+
+--echo
+
+explain
+SELECT MAX(t1.int_key), t1.int_key
+FROM t1 STRAIGHT_JOIN t2
+ORDER BY t1.int_key;
+
+--echo
+
+DROP TABLE t1,t2;
+
+SET join_cache_level=default;
+
+--echo #
+--echo # Regression test for
+--echo # Bug#46733 - NULL value not returned for aggregate on empty result
+--echo # set w/ semijoin on
+--echo #
+
+CREATE TABLE t1 (
+ i int(11) NOT NULL,
+ v varchar(1) DEFAULT NULL,
+ PRIMARY KEY (i)
+);
+
+INSERT INTO t1 VALUES (10,'a'),(11,'b'),(12,'c'),(13,'d');
+
+CREATE TABLE t2 (
+ i int(11) NOT NULL,
+ v varchar(1) DEFAULT NULL,
+ PRIMARY KEY (i)
+);
+
+INSERT INTO t2 VALUES (1,'x'),(2,'y');
+
+--echo
+
+SELECT MAX(t1.i)
+FROM t1 JOIN t2 ON t2.v
+ORDER BY t2.v;
+
+--echo
+
+EXPLAIN
+SELECT MAX(t1.i)
+FROM t1 JOIN t2 ON t2.v
+ORDER BY t2.v;
+
+--echo
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #45092: join buffer contains two blob columns one of which is
+--echo # used in the key employed to access the joined table
+--echo #
+
+CREATE TABLE t1 (c1 int, c2 int, key (c2));
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t1 VALUES (2,2);
+
+CREATE TABLE t2 (c1 text, c2 text);
+INSERT INTO t2 VALUES('tt', 'uu');
+INSERT INTO t2 VALUES('zzzz', 'xxxxxxxxx');
+
+--disable_result_log
+ANALYZE TABLE t1,t2;
+--enable_result_log
+
+set join_cache_level=6;
+
+SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH(t2.c2) FROM t1,t2
+ WHERE t1.c2=LENGTH(t2.c2) and t1.c1=LENGTH(t2.c1);
+
+set join_cache_level=default;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #51092: linked join buffer is used for a 3-way cross join query
+--echo # that selects only records of the first table
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,2);
+create table t3 (a int, b int);
+insert into t3 values (1,1),(2,2);
+
+explain select t1.* from t1,t2,t3;
+select t1.* from t1,t2,t3;
+
+set join_cache_level=2;
+
+explain select t1.* from t1,t2,t3;
+select t1.* from t1,t2,t3;
+
+set join_cache_level=default;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # Bug #52394: using join buffer for 3 table join with ref access
+--echo # LP #623209: and no references to the columns of the middle table
+--echo #
+
+
+set join_cache_level=6;
+
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (6,'r'),(27,'o');
+
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES(1),(2),(3),(4),(5);
+
+CREATE TABLE t3 (a int(11) primary key, b varchar(1));
+INSERT INTO t3 VALUES
+(14,'d'),(15,'z'),(16,'e'),(17,'h'),(18,'b'),(19,'s'),(20,'e'),
+(21,'j'),(22,'e'),(23,'f'),(24,'v'),(25,'x'),(26,'m'),(27,'o');
+
+EXPLAIN
+SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
+SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
+
+DROP TABLE t1,t2,t3;
+
+set join_cache_level=default;
+
+--echo #
+--echo # Bug #51084: Batched key access crashes for SELECT with
+--echo # derived table and LEFT JOIN
+--echo #
+
+CREATE TABLE t1 (
+ carrier int,
+ id int PRIMARY KEY
+);
+INSERT INTO t1 VALUES (1,11),(1,12),(2,13);
+
+CREATE TABLE t2 (
+ scan_date int,
+ package_id int
+);
+INSERT INTO t2 VALUES (2008,21),(2008,22);
+
+CREATE TABLE t3 (
+ carrier int PRIMARY KEY,
+ id int
+);
+INSERT INTO t3 VALUES (1,31);
+
+CREATE TABLE t4 (
+ carrier_id int,
+ INDEX carrier_id(carrier_id)
+);
+INSERT INTO t4 VALUES (31),(32);
+
+SET join_cache_level=8;
+
+SELECT COUNT(*)
+ FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+ ON t3.carrier = t1.carrier;
+
+EXPLAIN
+SELECT COUNT(*)
+ FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+ ON t3.carrier = t1.carrier;
+
+SET join_cache_level=default;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #52636: allowing JOINs on NULL values w/ join_cache_level = 5-8
+--echo #
+
+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);
+
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--sorted_result
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+
+set join_cache_level = 8;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--sorted_result
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+
+# test crash when no key is worth collecting by BKA for t2's ref
+delete from t1;
+INSERT INTO t1 VALUES (NULL),(NULL);
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--sorted_result
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+
+DROP TABLE t1,t2;
+
+# test varchar keys
+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");
+
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--sorted_result
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+
+set join_cache_level = 8;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--sorted_result
+SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+
+set join_cache_level = default;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #54359: Extra rows with join_cache_level=7,8 and two joins
+--echo # and multi-column index"
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL,
+ a int DEFAULT NULL,
+ b varchar(16) DEFAULT NULL,
+ c varchar(16) DEFAULT NULL,
+ INDEX idx (b,a))
+;
+
+INSERT INTO t1 VALUES (4,9,'k','k');
+INSERT INTO t1 VALUES (12,5,'k','k');
+
+set join_cache_level = 8;
+
+EXPLAIN
+SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx)
+ WHERE s.pk AND s.a >= t.pk AND s.b = t.c;
+
+SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx)
+ WHERE s.pk AND s.a >= t.pk AND s.b = t.c;
+
+set join_cache_level = default;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug #54235: Extra rows with join_cache_level=6,8 and two LEFT JOINs
+--echo #
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+
+INSERT INTO t1 VALUES (null), (2), (null), (1);
+
+set join_cache_level = 6;
+EXPLAIN
+SELECT t1.a
+ FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
+ WHERE t1.a OR t3.a;
+SELECT t1.a
+ FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
+ WHERE t1.a OR t3.a;
+
+EXPLAIN
+SELECT t1.a
+ FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
+ WHERE t1.a OR t4.a;
+SELECT t1.a
+ FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
+ WHERE t1.a OR t4.a;
+
+set join_cache_level = default;
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #663840: Memory overwrite causing crash with hash join
+--echo #
+
+SET SESSION join_cache_level=3;
+SET SESSION join_buffer_size=100;
+
+CREATE TABLE t3 (
+ i int NOT NULL,
+ j int NOT NULL,
+ d date NOT NULL,
+ t time NOT NULL,
+ v varchar(1) NOT NULL,
+ u varchar(1) NOT NULL,
+ INDEX idx (v)
+) COLLATE=latin1_bin;
+
+INSERT INTO t3 VALUES
+ (3,8,'2008-12-04','00:00:00','v','v'), (3,8,'2009-03-28','00:00:00','f','f'),
+ (3,5,'1900-01-01','00:55:47','v','v'), (2,8,'2009-10-02','00:00:00','s','s'),
+ (1,8,'1900-01-01','20:51:59','a','a'), (0,6,'2008-06-04','09:47:27','p','p'),
+ (8,7,'2009-01-13','21:58:29','z','z'), (5,2,'1900-01-01','22:45:53','a','a'),
+ (9,5,'2008-01-28','14:06:48','h','h'), (5,7,'2004-09-18','22:17:16','h','h'),
+ (4,2,'2006-10-14','14:59:37','v','v'), (2,9,'1900-01-01','23:37:40','v','v'),
+ (33,142,'2000-11-28','14:14:01','b','b'), (5,3,'2008-04-04','02:54:19','y','y'),
+ (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');
+
+CREATE TABLE t1 SELECT * FROM t3;
+DELETE FROM t1 WHERE i > 8;
+CREATE TABLE t2 SELECT * FROM t3;
+DELETE FROM t2 WHERE j > 10;
+
+EXPLAIN
+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;
+
+--sorted_result
+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;
+
+DROP TABLE t1,t2,t3;
+
+SET SESSION join_cache_level=DEFAULT;
+SET SESSION join_buffer_size=DEFAULT;
+
+
+--echo #
+--echo # Bug #664508: 'Simple' GROUP BY + ORDER BY
+--echo # when join buffers are used
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+ PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2 (v,i)
+) COLLATE latin1_bin;
+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');
+
+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)
+) COLLATE latin1_bin;
+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');
+
+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)
+) COLLATE latin1_bin;
+INSERT INTO t3 VALUES
+ (1,9,'x'), (2,5,'g'), (3,1,'o'), (4,0,'g'), (5,1,'v'),
+ (6,190,'m'), (7,6,'x'), (8,3,'c'), (9,4,'z'), (10,3,'i'),
+ (11,186,'x'), (12,1,'g'), (13,8,'q'), (14,226,'m'), (15,133,'p'),
+ (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
+ 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
+ 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
+ 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
+ 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
+ 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
+ GROUP BY t2.v ORDER BY t1.pk,t2.v;
+
+DROP TABLE t1,t2,t3;
+
+SET SESSION join_cache_level=DEFAULT;
+
+--echo #
+--echo # Bug #668290: hash join with non-binary collations
+--echo #
+
+CREATE TABLE t1 (
+ i int DEFAULT NULL,
+ cl varchar(10) CHARACTER SET latin1 DEFAULT NULL,
+ cu varchar(10) CHARACTER SET utf8 DEFAULT NULL,
+ INDEX cl (cl),
+ INDEX cu (cu)
+);
+INSERT INTO t1 VALUES
+ (650903552,'cmxffkpsel','z'), (535298048,'tvtjrcmxff','y'),
+ (1626865664,'when','for'), (39649280,'rcvljitvtj','ercvljitvt'),
+ (792068096,'ttercvljit','jttercvlji');
+INSERT INTO t1 SELECT * FROM t1;
+
+CREATE TABLE t2 (
+ cu varchar(10) CHARACTER SET utf8 DEFAULT NULL,
+ i int DEFAULT NULL,
+ cl varchar(10) CHARACTER SET latin1 DEFAULT NULL,
+ INDEX cu (cu),
+ INDEX cl (cl)
+);
+INSERT INTO t2 VALUES
+ ('g',7,'like'), ('fujttercvl',6,'y'),
+ ('s',2,'e'), ('didn\'t',0,'v'),
+ ('gvdrodpedk',8,'chogvdrodp'), ('jichogvdro',7,'will');
+
+EXPLAIN
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+
+SET SESSION join_cache_level = 4;
+
+EXPLAIN
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ;
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #669382: hash join using a ref with constant key parts
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES
+ (9), (11), (7), (8), (4), (1), (12), (3), (5);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+
+CREATE TABLE t2 (a int, b int, c int, INDEX idx (a,b));
+INSERT INTO t2 VALUES
+ (8, 80, 800), (1, 10, 100), (1, 11, 101), (3, 30, 300),
+ (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);
+
+SET SESSION join_cache_level = 4;
+SET SESSION join_buffer_size = 192;
+
+EXPLAIN
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #671901: hash join using a ref to a varchar field
+--echo #
+
+CREATE TABLE t1 (
+ v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ i int DEFAULT NULL
+);
+INSERT INTO t1 VALUES
+ ('k',8), ('abcdefjh',-575340544), ('f',77), ('because', 2), ('f',-517472256),
+ ('abcdefjhj',5), ('z',7);
+
+CREATE TABLE t2 (
+ v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ i int DEFAULT NULL,
+ INDEX idx (v)
+);
+INSERT INTO t2 VALUES
+ ('did',5), ('was',-1631322112), ('are',3), ('abcdefjhjk',3),
+ ('abcdefjhjk',4), ('tell',-824573952), ('t',0),('v',-1711013888),
+ ('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464),
+ ('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296),
+ ('ff', 5), ('abcdefjhjk',-1074397184);
+
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+#--echo #
+--echo # Bug #672497: 3 way join with tiny incremental join buffer with
+--echo # and a ref access from the first table
+--echo #
+
+CREATE TABLE t1 (
+ pk int PRIMARY KEY,
+ v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ INDEX idx (v)
+);
+INSERT INTO t1 VALUES
+ (1,'abcdefjhjk'), (2,'i'),(3,'abcdefjhjk'), (4,'well'), (5,'abcdefjhjk'),
+ (6,'abcdefjhjk'), (7,'that');
+
+CREATE TABLE t2 (
+ pk int PRIMARY KEY,
+ i int DEFAULT NULL,
+ v varchar(1000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ INDEX idx (v)
+);
+INSERT INTO t2 VALUES
+ (1,6,'yes'), (2,NULL,'will'), (3,NULL,'o'), (4,NULL,'k'), (5,NULL,'she'),
+ (6,-1450835968,'abcdefjhjkl'), (7,-975831040,'abcdefjhjkl'), (8,NULL,'z'),
+ (10,-343932928,'t'),
+ (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');
+
+CREATE TABLE t3 (
+ pk int NOT NULL PRIMARY KEY,
+ i int,
+ v varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ INDEX idx (v(333))
+);
+INSERT INTO t3 VALUES
+(1,7,'abcdefjhjkl'),(2,6,'y'), (3,NULL,'to'),(4,7,'n'),(5,7,'look'), (6,NULL,'all'),
+(7,1443168256,'c'), (8,1427046400,'right'),
+(11,7,'abcdefjhjkl'), (12,6,'y'), (13,NULL,'to'), (14,7,'n'), (15,7,'look'),
+(16,NULL,'all'), (17,1443168256,'c'), (18,1427046400,'right'),
+(21,7,'abcdefjhjkl'), (22,6,'y'), (23,NULL,'to'), (24,7,'n'), (25,7,'look'),
+(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');
+
+SET SESSION join_buffer_size = 192;
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT t3.i FROM t1,t2,t3
+ WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0;
+SELECT t3.i FROM t1,t2,t3
+ WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0;
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #672551: hash join over a long varchar field
+--echo #
+
+CREATE TABLE t1 (
+ pk int PRIMARY KEY,
+ a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
+ INDEX idx (a)
+);
+INSERT INTO t1 VALUES (2, 'aa'), (5, 'ccccccc'), (3, 'bb');
+
+CREATE TABLE t2(
+ pk int PRIMARY KEY,
+ a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
+ INDEX idx (a)
+);
+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');
+
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #674431: nested outer join when join_cache_level is set to 7
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(32)) ;
+INSERT INTO t1 VALUES (5,'h'), (NULL,'j');
+CREATE TABLE t2 (a int, b varchar(32), c int) ;
+INSERT INTO t2 VALUES (5,'h',100), (NULL,'j',200);
+CREATE TABLE t3 (a int, b varchar(32), INDEX idx(b));
+INSERT INTO t3 VALUES (77,'h'), (88,'g');
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 7;
+SELECT t3.a
+ FROM t1 LEFT JOIN
+ (t2 LEFT OUTER JOIN t3 ON t2.b = t3.b) ON t2.a = t1.b
+ WHERE t3.a BETWEEN 3 AND 11 OR t1.a <= t2.c;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #52540: nested outer join when join_cache_level is set to 3
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2);
+CREATE TABLE t2 (a varchar(10));
+INSERT INTO t2 VALUES ('f'),('x');
+CREATE TABLE t3 (pk int(11) PRIMARY KEY);
+INSERT INTO t3 VALUES (2);
+CREATE TABLE t4 (a varchar(10));
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+SET SESSION join_cache_level = 3;
+
+SELECT *
+ FROM t2 LEFT JOIN
+ ((t1 JOIN t3 ON t1.a = t3.pk) LEFT JOIN t4 ON 1) ON 1;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #674423: outer join with ON expression over only outer tables
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES ('9');
+
+CREATE TABLE t2 (pk int, a int) ;
+INSERT INTO t2 VALUES ('9',NULL), ('1',NULL);
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9;
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <>0 OR t2.pk < 9;
+
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9;
+SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #675095: nested outer join using join buffer
+--echo #
+
+CREATE TABLE t1 (pk int, a1 int) ;
+INSERT IGNORE INTO t1 VALUES (2,NULL), (8,0);
+
+CREATE TABLE t2 (pk int, a2 int, c2 int, d2 int) ;
+INSERT IGNORE INTO t2 VALUES (9,0,0,2), (1,0,0,7);
+
+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);
+
+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';
+
+SET SESSION join_cache_level = 0;
+
+EXPLAIN EXTENDED
+SELECT *
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+ LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+SELECT *
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+ LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+
+SET SESSION join_cache_level = 2;
+
+EXPLAIN EXTENDED
+SELECT *
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+ LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+SELECT *
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+ LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+
+SET SESSION join_cache_level = 1;
+
+EXPLAIN EXTENDED
+SELECT *
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+ LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+SELECT *
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2)
+ LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # Bug #675516: nested outer join with 3 tables in the nest
+--echo # using BNL + BNLH
+--echo #
+
+CREATE TABLE t1 (a1 int, b1 int, c1 int) ;
+INSERT INTO t1 VALUES (7,8,0), (6,4,0);
+
+CREATE TABLE t2 (a2 int) ;
+INSERT INTO t2 VALUES (5);
+
+CREATE TABLE t3 (a3 int, b3 int, c3 int, PRIMARY KEY (b3)) ;
+INSERT INTO t3 VALUES (2,5,0);
+
+CREATE TABLE t4 (a4 int, b4 int, c4 int) ;
+INSERT INTO t4 VALUES (7,8,0);
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM
+ t1 LEFT JOIN
+ ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+ WHERE t3.a3 IS NULL;
+SELECT * FROM
+ t1 LEFT JOIN
+ ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+ WHERE t3.a3 IS NULL;
+
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT * FROM
+ t1 LEFT JOIN
+ ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+ WHERE t3.a3 IS NULL;
+SELECT * FROM
+ t1 LEFT JOIN
+ ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3
+ WHERE t3.a3 IS NULL;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #660963: nested outer join with join_cache_level set to 5
+--echo #
+
+CREATE TABLE t1 (a1 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 (a2 int, b2 int, PRIMARY KEY (a2)) ;
+INSERT INTO t2 VALUES (2,1);
+
+CREATE TABLE t3 (a3 int, b3 int, PRIMARY KEY (a3)) ;
+INSERT INTO t3 VALUES (2,1);
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+
+SET SESSION join_cache_level = 6;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+
+SET SESSION join_cache_level = 5;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #675922: incremental buffer for BKA with access from previous
+--echo # buffers from non-nullable columns whose values may be null
+--echo #
+
+CREATE TABLE t1 (a1 varchar(32)) ;
+INSERT INTO t1 VALUES ('s'),('k');
+
+CREATE TABLE t2 (a2 int PRIMARY KEY, b2 varchar(32)) ;
+INSERT INTO t2 VALUES (7,'s');
+
+CREATE TABLE t3 (a3 int PRIMARY KEY, b3 varchar(32)) ;
+INSERT INTO t3 VALUES (7,'s');
+
+CREATE TABLE t4 (a4 int) ;
+INSERT INTO t4 VALUES (9);
+
+CREATE TABLE t5(a5 int PRIMARY KEY, b5 int) ;
+INSERT INTO t5 VALUES (7,0);
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT t4.a4, t5.b5
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+ LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+SELECT t4.a4, t5.b5
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+ LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+
+SET SESSION join_cache_level = 6;
+EXPLAIN
+SELECT t4.a4, t5.b5
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+ LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+SELECT t4.a4, t5.b5
+ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
+ LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=off';
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # Bug #670380: hash join for non-binary collation
+--echo #
+
+
+CREATE TABLE t1 (pk int PRIMARY KEY, a varchar(32));
+CREATE TABLE t2 (pk int PRIMARY KEY, a varchar(32), INDEX idx(a));
+INSERT INTO t1 VALUES
+ (10,'AAA'), (20,'BBBB'), (30,'Cc'), (40,'DD'), (50,'ee');
+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');
+
+SET SESSION join_cache_level = 4;
+
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a=t2.a;
+SELECT * FROM t1,t2 WHERE t1.a=t2.a;
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #694092: incorrect detection of index only pushdown conditions
+--echo #
+
+CREATE TABLE t1 (
+ f1 varchar(10), f3 int(11), PRIMARY KEY (f3)
+);
+INSERT INTO t1 VALUES ('y',1),('or',5);
+
+CREATE TABLE t2 (
+ f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3)
+);
+INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m');
+
+SET SESSION join_cache_level = 1;
+
+SET SESSION optimizer_switch = 'index_condition_pushdown=off';
+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);
+SELECT * FROM t1,t2
+ WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
+
+SET SESSION optimizer_switch = 'index_condition_pushdown=on';
+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);
+SELECT * FROM t1,t2
+ WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION optimizer_switch = DEFAULT;
+
+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 6ae7fb6dfee..e36d861f8bb 100644
--- a/mysql-test/t/join_nested.test
+++ b/mysql-test/t/join_nested.test
@@ -462,7 +462,6 @@ SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
LEFT JOIN
(t1,t2)
ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
-
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
@@ -1236,5 +1235,6 @@ SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a
DROP TABLE t1, t2, t3;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/join_nested_jcl6.test b/mysql-test/t/join_nested_jcl6.test
new file mode 100644
index 00000000000..5737cfe115f
--- /dev/null
+++ b/mysql-test/t/join_nested_jcl6.test
@@ -0,0 +1,101 @@
+#
+# Run join_nested.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/join_nested.test
+
+#
+# BUG#35835: queries with nested outer joins with BKA enabled
+#
+
+CREATE TABLE t5 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+CREATE TABLE t6 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+CREATE TABLE t7 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+CREATE TABLE t8 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
+
+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);
+
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5
+ LEFT JOIN
+ (
+ (t6, t7)
+ LEFT JOIN
+ 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);
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5
+ LEFT JOIN
+ (
+ (t6, t7)
+ LEFT JOIN
+ 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);
+
+DELETE FROM t5;
+DELETE FROM t6;
+DELETE FROM t7;
+DELETE FROM t8;
+
+INSERT INTO t5 VALUES (1,3,0), (3,2,0);
+INSERT INTO t6 VALUES (3,3,0);
+INSERT INTO t7 VALUES (1,2,0);
+INSERT INTO t8 VALUES (1,1,0);
+
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5 LEFT JOIN
+ (t6 LEFT JOIN t7 ON t7.a=1, t8)
+ ON (t5.b=t8.b);
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5 LEFT JOIN
+ (t6 LEFT JOIN t7 ON t7.a=1, t8)
+ ON (t5.b=t8.b);
+
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5 LEFT JOIN
+ (t6 LEFT JOIN t7 ON t7.b=2, t8)
+ ON (t5.b=t8.b);
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5 LEFT JOIN
+ (t6 LEFT JOIN t7 ON t7.b=2, t8)
+ ON (t5.b=t8.b);
+
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5 LEFT JOIN
+ (t8, t6 LEFT JOIN t7 ON t7.a=1)
+ ON (t5.b=t8.b);
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5 LEFT JOIN
+ (t8, t6 LEFT JOIN t7 ON t7.a=1)
+ ON (t5.b=t8.b);
+
+DROP TABLE t5,t6,t7,t8;
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index c8fa2a35538..28526a30ae7 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -310,6 +310,7 @@ insert into t1 values (1, 2, 11), (1, 2, 7), (2, 2, 8), (1,2,9),(1,3,9);
insert into t2 values (1, 2, 3),(2, 2, 8), (4,3,9),(3,2,10);
select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
t1.m = t2.m where t1.n = 1;
+--sorted_result
select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
t1.m = t2.m where t1.n = 1 order by t1.o;
drop table t1,t2;
@@ -1075,6 +1076,7 @@ show status like "handler_read%";
drop table t1,t2,t3;
+--echo #
--echo # Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
--echo #
diff --git a/mysql-test/t/join_outer_jcl6.test b/mysql-test/t/join_outer_jcl6.test
new file mode 100644
index 00000000000..be98e7503ad
--- /dev/null
+++ b/mysql-test/t/join_outer_jcl6.test
@@ -0,0 +1,17 @@
+#
+# Run join_outer.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/join_outer.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 742a83f7bad..f05821af5a8 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -24,7 +24,7 @@ connection reader;
# Sleep a bit till the update of connection writer is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update low_priority t1 set n = 4";
+ where state = "Table lock" and info = "update low_priority t1 set n = 4";
--source include/wait_condition.inc
send
select n from t1;
@@ -32,7 +32,7 @@ connection locker;
# Sleep a bit till the select of connection reader is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "select n from t1";
+ where state = "Table lock" and info = "select n from t1";
--source include/wait_condition.inc
unlock tables;
connection writer;
@@ -52,7 +52,7 @@ connection reader;
# Sleep a bit till the update of connection writer is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update low_priority t1 set n = 4";
+ where state = "Table Lock" and info = "update low_priority t1 set n = 4";
--source include/wait_condition.inc
select n from t1;
connection locker;
@@ -96,7 +96,7 @@ insert t1 select * from t2;
connection locker;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert t1 select * from t2";
+ where state = "Table Lock" and info = "insert t1 select * from t2";
--source include/wait_condition.inc
drop table t2;
connection reader;
@@ -120,7 +120,7 @@ connection locker;
# Sleep a bit till the insert of connection reader is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert t1 select * from t2";
+ where state = "Table Lock" and info = "insert t1 select * from t2";
--source include/wait_condition.inc
drop table t2;
connection reader;
@@ -299,7 +299,7 @@ connection reader;
# Wait till connection writer is blocked
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "alter table t1 auto_increment=0";
+ where state = "Table Lock" and info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
send
alter table t1 auto_increment=0;
@@ -307,7 +307,7 @@ connection locker;
# Wait till connection reader is blocked
let $wait_condition=
select count(*) = 2 from information_schema.processlist
- where state = "Locked" and info = "alter table t1 auto_increment=0";
+ where state = "Table Lock" and info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
unlock tables;
connection writer;
@@ -462,16 +462,16 @@ update t1 set i= 10;
connection reader;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update t1 set i= 10";
+ where state = "Table Lock" and info = "update t1 set i= 10";
--source include/wait_condition.inc
send
select * from t1;
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "select * from t1";
+ where state = "Table Lock" and info = "select * from t1";
--source include/wait_condition.inc
-let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
+let $ID= `select id from information_schema.processlist where state = "Table Lock" and info = "update t1 set i= 10"`;
--replace_result $ID ID
eval kill query $ID;
connection reader;
@@ -606,7 +606,7 @@ connection waiter;
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert into t1 values(1)";
+ where state = "Table Lock" and info = "insert into t1 values(1)";
--source include/wait_condition.inc
let $tlwb= `show status like 'Table_locks_waited'`;
unlock tables;
diff --git a/mysql-test/t/maria_mrr.test b/mysql-test/t/maria_mrr.test
new file mode 100644
index 00000000000..988591d742d
--- /dev/null
+++ b/mysql-test/t/maria_mrr.test
@@ -0,0 +1,127 @@
+-- source include/have_maria.inc
+#
+# MRR/Maria tests.
+#
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+--enable_warnings
+
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+
+set @save_storage_engine= @@storage_engine;
+set storage_engine=aria;
+
+--source include/mrr_tests.inc
+set storage_engine= @save_storage_engine;
+
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+
+--echo #
+--echo # Crash in quick_range_seq_next() in maria-5.3-dsmrr-cpk with join_cache_level = {8,1}
+--echo #
+set @save_join_cache_level= @@join_cache_level;
+SET SESSION join_cache_level = 8;
+CREATE TABLE `t1` (
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO `t1` VALUES (6,'2005-10-07 00:00:00','e','e');
+INSERT INTO `t1` VALUES (51,'2000-07-15 05:00:34','f','f');
+CREATE TABLE `t2` (
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO `t2` VALUES (2,'2004-10-11 18:13:16','w','w');
+INSERT INTO `t2` VALUES (2,'1900-01-01 00:00:00','d','d');
+SELECT table2 .`col_datetime_key`
+FROM t2 JOIN ( t1 table2 JOIN t2 table3 ON table3 .`col_varchar_key` < table2 .`col_varchar_key` ) ON table3 .`col_varchar_nokey` ;
+
+drop table t1, t2;
+set join_cache_level=@save_join_cache_level;
+
+#
+# Bug #665049: index condition pushdown with Maria
+#
+
+CREATE TABLE t1(
+ pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+ PRIMARY KEY (pk), INDEX idx (v, i)
+) ENGINE=ARIA;
+INSERT INTO t1 VALUES
+ (1,9,'x'), (2,5,'g'), (3,1,'o'), (4,0,'g'), (5,1,'v'),
+ (6,190,'m'), (7,6,'x'), (8,3,'c'), (9,4,'z'), (10,3,'i'),
+ (11,186,'x'), (12,1,'g'), (13,8,'q'), (14,226,'m'), (15,133,'p');
+
+CREATE TABLE t2(
+ pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+ PRIMARY KEY (pk), INDEX idx (v, i)
+) ENGINE=ARIA;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t2 VALUES (77, 333, 'z');
+
+CREATE TABLE t3(
+ 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') ;
+
+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;
+EXPLAIN
+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;
+
+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;
+EXPLAIN
+ 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;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#671361: virtual int Mrr_ordered_index_reader::refill_buffer(): Assertion `!know_key_tuple_params
+--echo # (works only on Maria because we need 1024-byte long key)
+--echo #
+
+SET SESSION optimizer_use_mrr = 'force';
+SET SESSION join_cache_level = 6;
+SET SESSION join_buffer_size = 1024;
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL,
+ 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');
+
+CREATE TABLE t2 (
+ col_varchar_10_latin1 varchar(10) DEFAULT NULL
+) ENGINE=Aria;
+INSERT INTO t2 VALUES ('foo'), ('foo');
+
+EXPLAIN SELECT count(*)
+FROM t1 AS table1, t2 AS table2
+WHERE
+ table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ;
+
+SELECT count(*)
+FROM t1 AS table1, t2 AS table2
+WHERE
+ table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ;
+
+drop table t1, t2;
diff --git a/mysql-test/t/merge-big.test b/mysql-test/t/merge-big.test
index d39c2973688..10a41b609a0 100644
--- a/mysql-test/t/merge-big.test
+++ b/mysql-test/t/merge-big.test
@@ -52,7 +52,7 @@ connection default;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE ID = $con1_id AND STATE = 'Locked';
+ WHERE ID = $con1_id AND STATE = "Table Lock";
--source include/wait_condition.inc
#SELECT NOW();
--echo # Kick INSERT out of thr_multi_lock().
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index d405e4e5e3a..e5c7a415170 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -498,9 +498,9 @@ send alter table t1 add column c int default 100 after a;
connect (updater,localhost,root,,test);
connection updater;
# Wait till "alter table t1 ..." of session changer is in work.
-# = There is one session is in state "Locked".
+# = There is one session is in state "Table Lock".
let $wait_condition= select count(*)= 1 from information_schema.processlist
- where state= 'Locked';
+ where state= "Table Lock";
--source include/wait_condition.inc
send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
@@ -509,9 +509,9 @@ connection locker;
# - "alter table t1 ..." of session changer and
# - "update t1, v1 ..." of session updater
# are in work.
-# = There are two session is in state "Locked".
+# = There are two session is in state "Table Lock".
let $wait_condition= select count(*)= 2 from information_schema.processlist
- where state= 'Locked';
+ where state= "Table Lock";
--source include/wait_condition.inc
unlock tables;
diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test
new file mode 100644
index 00000000000..82457ee4366
--- /dev/null
+++ b/mysql-test/t/myisam_mrr.test
@@ -0,0 +1,220 @@
+#
+# MRR/MyISAM tests.
+#
+
+--disable_warnings
+drop table if exists t0, t1, t2, t3;
+--enable_warnings
+
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=79;
+
+-- source include/mrr_tests.inc
+
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+
+#
+# BUG#30622: Incorrect query results for MRR + filesort
+#
+CREATE TABLE t1 (
+ ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+ col1 int(10) unsigned DEFAULT NULL,
+ key1 int(10) unsigned NOT NULL DEFAULT '0',
+ key2 int(10) unsigned DEFAULT NULL,
+ text1 text,
+ text2 text,
+ col2 smallint(6) DEFAULT '100',
+ col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+ col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID),
+ KEY (key1),
+ KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES
+(1,NULL,1130,NULL,'Hello',NULL,100,'bodyandsubject',0),
+(2,NULL,1130,NULL,'bye',NULL,100,'bodyandsubject',0),
+(3,NULL,1130,NULL,'red',NULL,100,'bodyandsubject',0),
+(4,NULL,1130,NULL,'yellow',NULL,100,'bodyandsubject',0),
+(5,NULL,1130,NULL,'blue',NULL,100,'bodyandsubject',0);
+
+select * FROM t1 WHERE key1=1130 AND col1 IS NULL ORDER BY text1;
+
+drop table t1;
+
+
+--echo
+--echo BUG#37851: Crash in test_if_skip_sort_order tab->select is zero
+--echo
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ int_key int(11) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY int_key (int_key)
+);
+INSERT INTO t2 VALUES (1,1),(2,6),(3,0);
+
+EXPLAIN EXTENDED
+SELECT MIN(t1.pk)
+FROM t1 WHERE EXISTS (
+ SELECT t2.pk
+ FROM t2
+ WHERE t2.int_key IS NULL
+ GROUP BY t2.pk
+);
+
+DROP TABLE t1, t2;
+
+-- echo #
+-- echo # BUG#42048 Discrepancy between MyISAM and Maria's ICP implementation
+-- echo #
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b char(20), filler char(200), key(a,b(10)));
+insert into t1 select A.a + 10*(B.a + 10*C.a), 'bbb','filler' from t0 A, t0 B, t0 C;
+update t1 set b=repeat(char(65+a), 20) where a < 25;
+
+--echo This must show range + using index condition:
+explain select * from t1 where a < 10 and b = repeat(char(65+a), 20);
+select * from t1 where a < 10 and b = repeat(char(65+a), 20);
+drop table t0,t1;
+
+-- echo #
+-- echo # BUG#41136: ORDER BY + range access: EXPLAIN shows "Using MRR" while MRR is actually not used
+-- echo #
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, key(a));
+insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 A, t0 B, t0 C;
+-- echo This mustn't show "Using MRR":
+explain select * from t1 where a < 20 order by a;
+drop table t0, t1;
+
+-- echo #
+-- echo # Part of MWL#67: DS-MRR backport: add an @@optimizer_switch flag for
+-- echo # index_condition pushdown:
+-- echo # - engine_condition_pushdown does not affect ICP
+
+
+# Check that optimizer_switch is present
+select @@optimizer_switch like '%index_condition_pushdown=on%';
+
+# Check if it affects ICP
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, key(a));
+insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 A, t0 B, t0 C;
+
+-- echo A query that will use ICP:
+explain select * from t1 where a < 20;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='index_condition_pushdown=off';
+explain select * from t1 where a < 20;
+
+set optimizer_switch='index_condition_pushdown=on';
+explain select * from t1 where a < 20;
+
+set optimizer_switch=@save_optimizer_switch;
+
+
+--echo #
+--echo # BUG#629684: Unreachable code in multi_range_read.cc in maria-5.3-dsmrr-cpk
+--echo #
+
+delete from t0 where a > 2;
+insert into t0 values (NULL),(NULL);
+insert into t1 values (NULL, 1234), (NULL, 5678);
+
+set @save_join_cache_level=@@join_cache_level;
+set @@join_cache_level=6;
+explain
+select * from t0, t1 where t0.a<=>t1.a;
+select * from t0, t1 where t0.a<=>t1.a;
+
+set @@join_cache_level=@save_join_cache_level;
+drop table t0, t1;
+
+--echo #
+--echo # BUG#625841: Assertion `!table || (!table->read_set || bitmap_is_set
+--echo # (table->read_set, field_index))' on REPLACE ... SELECT with MRR
+--echo #
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (
+ key1 varchar(10),
+ col1 char(255), col2 char(255),
+ col3 char(244), col4 char(255),
+ key(key1)
+);
+create table t2 like t1;
+
+insert into t1
+select
+ 1000+A.a+100*B.a + 10*C.a,
+ 'col1val', 'col2val',
+ 'col3val', 'col4val'
+from t0 A, t0 B, t0 C;
+
+REPLACE INTO t2(col2,col3,col4)
+SELECT col2,col3,col4
+FROM t1
+WHERE `key1` LIKE CONCAT( LEFT( '1' , 7 ) , '%' )
+ORDER BY col1 LIMIT 7;
+drop table t0, t1, t2;
+
+--echo #
+--echo # BUG#670417: Diverging results in maria-5.3-mwl128-dsmrr-cpk with join buffer (incremental, BKA join)
+--echo #
+
+set @save_join_cache_level = @@join_cache_level;
+set join_cache_level = 6;
+set @save_join_buffer_size=@@join_buffer_size;
+--disable_warnings
+set join_buffer_size = 136;
+--enable_warnings
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) NOT NULL,
+ col_varchar_key varchar(1) NOT NULL,
+ col_varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t1 VALUES
+ (10,8,'v','v'),(11,8,'f','f'), (12,5,'v','v'),
+ (13,8,'s','s'),(14,8,'a','a'),(15,6,'p','p'),
+ (16,7,'z','z'),(17,2,'a','a'),(18,5,'h','h'),
+ (19,7,'h','h'),(20,2,'v','v'),(21,9,'v','v'),
+ (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');
+
+SELECT COUNT(*)
+FROM
+ t1 AS table2, t1 AS table3
+where
+ table3.col_varchar_key = table2.col_varchar_key AND
+ table3.col_varchar_key = table2.col_varchar_nokey AND
+ table3.pk<>0;
+
+EXPLAIN SELECT COUNT(*)
+FROM
+ t1 AS table2, t1 AS table3
+where
+ table3.col_varchar_key = table2.col_varchar_key AND
+ table3.col_varchar_key = table2.col_varchar_nokey AND
+ table3.pk<>0;
+
+set join_cache_level= @save_join_cache_level;
+set join_buffer_size= @save_join_buffer_size;
+drop table t1;
+
diff --git a/mysql-test/t/optimizer_switch.test b/mysql-test/t/optimizer_switch.test
new file mode 100644
index 00000000000..713262197d4
--- /dev/null
+++ b/mysql-test/t/optimizer_switch.test
@@ -0,0 +1,113 @@
+--echo #
+--echo # Generic @@optimizer_switch tests
+--echo #
+--echo #
+
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='index_merge=off,index_merge_union=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='index_merge_union=on';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,index_merge_sort_union=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch=4;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch=NULL;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='default,index_merge';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=index_merge';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=on,but...';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='on';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=on,index_merge=off';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge_union=on,index_merge_union=default';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='default,index_merge=on,index_merge=off,default';
+
+set optimizer_switch=default;
+set optimizer_switch='index_merge=off,index_merge_union=off,default';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+set optimizer_switch=default;
+
+# Check setting defaults for global vars
+--replace_regex /,table_elimination=on//
+select @@global.optimizer_switch;
+set @@global.optimizer_switch=default;
+--replace_regex /,table_elimination=on//
+select @@global.optimizer_switch;
+
+--echo #
+--echo # Check index_merge's @@optimizer_switch flags
+--echo #
+--replace_regex /,table_elimination.on//
+select @@optimizer_switch;
+
+--echo
+--echo BUG#37120 optimizer_switch allowable values not according to specification
+--echo
+
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,materialization=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off,semijoin=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+set optimizer_switch=default;
+
+
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 0bacd785808..abad4f6b0e4 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -402,7 +402,11 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3');
EXPLAIN SELECT * FROM t1 WHERE FieldKey = '1' ORDER BY LongVal;
SELECT * FROM t1 WHERE FieldKey = '1' ORDER BY LongVal;
-EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+--echo DS-MRR: use two IGNORE INDEX queries, otherwise we get cost races, because
+--echo DS-MRR: records_in_range/read_time return the same numbers for all three indexes
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal;
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 9b3f3e750e1..0b8928b6038 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -163,6 +163,9 @@ create table t1
) engine = MYISAM ;
create table t2 like t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
prepare stmt1 from @stmt ;
execute stmt1 ;
@@ -171,6 +174,8 @@ explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2
deallocate prepare stmt1;
drop tables t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
#
# parameters from variables (for field creation)
#
diff --git a/mysql-test/t/query_cache_28249.test b/mysql-test/t/query_cache_28249.test
index 390a1ce6e3d..fd283aa69fb 100644
--- a/mysql-test/t/query_cache_28249.test
+++ b/mysql-test/t/query_cache_28249.test
@@ -64,12 +64,12 @@ connection user3;
# The values marked with 'X' must be reached.
--echo # Poll till the select of connection user1 is blocked by the write lock on t1.
let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = "Table Lock"
AND info = '$select_for_qc';
--source include/wait_condition.inc
eval
SELECT user,command,state,info FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = "Table Lock"
AND info = '$select_for_qc';
INSERT INTO t1 VALUES (4);
diff --git a/mysql-test/t/select_jcl6.test b/mysql-test/t/select_jcl6.test
new file mode 100644
index 00000000000..9f9a3a40e0f
--- /dev/null
+++ b/mysql-test/t/select_jcl6.test
@@ -0,0 +1,17 @@
+#
+# Run select.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/select.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index e4b6a5deefe..9b34a23bcc9 100644
--- a/mysql-test/t/sp_notembedded.test
+++ b/mysql-test/t/sp_notembedded.test
@@ -276,7 +276,7 @@ set session low_priority_updates=on;
connection rl_wait;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and
+ where state = "Table lock" and
info = "update t1 set value='updated' where value='old'";
--source include/wait_condition.inc
diff --git a/mysql-test/t/sp_sync.test b/mysql-test/t/sp_sync.test
index f9dae17b039..e7f952162ee 100644
--- a/mysql-test/t/sp_sync.test
+++ b/mysql-test/t/sp_sync.test
@@ -34,7 +34,7 @@ SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go';
connection con1;
let $wait_condition= SELECT 1 FROM information_schema.processlist WHERE ID = $ID AND
-state = "Locked";
+state = "Table lock";
--source include/wait_condition.inc
DROP TABLE t1, t2;
SET DEBUG_SYNC = 'now WAIT_FOR parked';
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index 5da210f5a69..505df0fe8dc 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -58,7 +58,7 @@ let $ID= `select connection_id()`;
connection con2;
--echo # Switched to connection: con2
# wait for the other query to start executing
-let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Locked";
+let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Table Lock";
--source include/wait_condition.inc
unlock tables;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 9bacaaaf6ec..6797c65bbcc 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1,8 +1,20 @@
+#
+# NOTE. Please do not switch connection inside this test.
+# subselect.test is included from several other test cases which set
+# explicit session properties that must be preserved throughout the test.
+# If you need to use a dedicated connection for a test case,
+# close the new connection and switch back to "default" as soon
+# as possible.
+#
# Initialise
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
--enable_warnings
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
select (select 2);
explain extended select (select 2);
SELECT (SELECT 1) UNION SELECT (SELECT 2);
@@ -811,17 +823,12 @@ create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
create table t3 (a int, b int, index a (a));
insert into t1 values (1,10), (2,20), (3,30), (4,40);
---disable_query_log
-begin;
# making table large enough
-let $1 = 10000;
-while ($1)
- {
- eval insert into t1 values (rand()*100000+200,rand()*100000);
- dec $1;
- }
-commit;
---enable_query_log
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+
insert into t2 values (2), (3), (4), (5);
insert into t3 values (10,3), (20,4), (30,5);
select * from t2 where t2.a in (select a from t1);
@@ -834,7 +841,7 @@ insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
-drop table t1, t2, t3;
+drop table t0, t1, t2, t3;
#
# alloc_group_fields() working
@@ -1494,12 +1501,13 @@ drop table t1;
#
# Subselect in non-select command just after connection
+# Disconnect new connection and switch back when test is finished
#
connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connection root;
set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
-connection default;
disconnect root;
+connection default;
#
# primary query with temporary table and subquery with grouping
@@ -2512,33 +2520,30 @@ DROP TABLE t1, t2;
#
# Bug#14654 Cannot select from the same table twice within a UNION statement
#
-CREATE TABLE t1 (i INT);
-
-(SELECT i FROM t1) UNION (SELECT i FROM t1);
-#TODO:not supported
---error ER_PARSE_ERROR
-SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
- (
- (SELECT i FROM t1) UNION
- (SELECT i FROM t1)
- );
-
-#TODO:not supported
---error ER_PARSE_ERROR
-SELECT * FROM t1
-WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
-
-#TODO:not supported
---error ER_PARSE_ERROR
-explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
- from t1;
-
+# disabled by psergey-merge:
+#CREATE TABLE t1 (i INT);
+#
+#(SELECT i FROM t1) UNION (SELECT i FROM t1);
+#SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
+# (
+# (SELECT i FROM t1) UNION
+# (SELECT i FROM t1)
+# );
+#
#TODO:not supported
---error ER_PARSE_ERROR
-explain select * from t1 where not exists
- ((select t11.i from t1 t11) union (select t12.i from t1 t12));
-
-DROP TABLE t1;
+#--error ER_PARSE_ERROR
+#SELECT * FROM t1
+#WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
+#
+##TODO:not supported
+#--error ER_PARSE_ERROR
+#explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
+# from t1;
+#
+#explain select * from t1 where not exists
+# ((select t11.i from t1 t11) union (select t12.i from t1 t12));
+#
+#DROP TABLE t1;
#
@@ -2605,27 +2610,16 @@ DROP TABLE t1,t2;
# slow with big sort_buffer_size
#
-CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
---disable_query_log
-begin;
-let $1=3000;
-while ($1)
-{
- eval INSERT INTO t1(a) VALUES(RAND()*1000);
- eval SELECT MAX(b) FROM t1 INTO @id;
- let $2=10;
- while ($2)
- {
- eval INSERT INTO t2(y,z) VALUES(@id,RAND()*1000);
- dec $2;
- }
- dec $1;
-}
-commit;
---enable_query_log
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+enable_query_log;
SET SESSION sort_buffer_size = 32 * 1024;
SELECT SQL_NO_CACHE COUNT(*)
@@ -2637,8 +2631,7 @@ SELECT SQL_NO_CACHE COUNT(*)
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
-DROP TABLE t1,t2;
-
+DROP TABLE t1,t2,t3;
#
# Bug#25219 EXIST subquery with UNION over a mix of
@@ -3094,6 +3087,53 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
DROP TABLE t1, t2;
#
+# Bug31048 Many nested subqueries may cause server crash.
+#
+#create table t1(a int,b int,key(a),key(b));
+#insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
+# (6,7),(7,4),(5,3);
+# TODO: enable the test after fixing 33266 in 6.0
+
+#let $nesting= 26;
+#let $should_work_nesting= 5;
+#let $start= select sum(a),a from t1 where a> ( select sum(a) from t1 ;
+#let $end= )group by a ;
+#let $start_app= where a> ( select sum(a) from t1 ;
+#let $end_pre= )group by b limit 1 ;
+
+#--disable_result_log
+#--disable_query_log
+# At least 4 level nesting should work without errors
+#while ($should_work_nesting)
+#{
+#--echo $should_work_nesting
+# eval $start $end;
+# eval explain $start $end;
+# let $start= $start
+# $start_app;
+# let $end= $end_pre
+# $end;
+# dec $should_work_nesting;
+#}
+# Other may fail with the 'stack overrun error'
+#while ($nesting)
+#{
+#--echo $nesting
+#--error 0,1436
+# eval $start $end;
+#--error 0,1436
+# eval explain $start $end;
+# let $start= $start
+# $start_app;
+# let $end= $end_pre
+# $end;
+# dec $nesting;
+#}
+#--enable_result_log
+#--enable_query_log
+#drop table t1;
+
+#
# Bug#28076 inconsistent binary/varbinary comparison
#
@@ -3195,52 +3235,45 @@ DROP TABLE t1;
#
# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122
#
-
-CREATE TABLE t1 (a INT);
-CREATE TABLE t2 (a INT);
-
-INSERT INTO t1 VALUES (1),(2);
-INSERT INTO t2 VALUES (1),(2);
-
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
-EXPLAIN EXTENDED
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
-
-
-#TODO:not supported
---error ER_PARSE_ERROR
-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));
-
-DROP TABLE t1,t2;
+# disabled by psergey-merge:
+#
+#CREATE TABLE t1 (a INT);
+#CREATE TABLE t2 (a INT);
+#
+#INSERT INTO t1 VALUES (1),(2);
+#INSERT INTO t2 VALUES (1),(2);
+#
+#SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+#EXPLAIN EXTENDED
+#SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=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));
+#
+#DROP TABLE t1,t2;
#
# Bug#33675 Usage of an uninitialized memory by filesort in a subquery
# caused server crash.
#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
insert into t1 values(1,1),(2,2), (3, 3);
-let $i=10000;
---disable_query_log
--disable_warnings
-begin;
-while ($i)
-{
- eval insert into t2 values (-1 , $i/5000 + 1, '$i');
- dec $i;
-}
-commit;
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
--enable_warnings
---enable_query_log
set session sort_buffer_size= 33*1024;
select count(*) from t1 where f12 =
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
-drop table t1,t2;
-
+drop table t0,t1,t2;
#
# Bug#33794 "MySQL crashes executing specific query on specific dump"
@@ -3403,6 +3436,183 @@ DROP TABLE t1,t2;
--echo End of 5.0 tests.
#
+# Test [NOT] IN truth table (both as top-level and general predicate).
+#
+
+create table t_out (subcase char(3),
+ a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+
+insert into t_out values ('A.1','2a', NULL, '2a');
+#------------------------- A.2 - impossible
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+-- echo
+-- echo Test general IN semantics (not top-level)
+-- echo
+-- echo case A.1
+select subcase,
+ (a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+
+-- echo case A.2 - impossible
+
+-- echo case A.3
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+
+-- echo case A.4
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+
+-- echo case B.1
+select subcase,
+ (a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+
+-- echo case B.2
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+
+-- echo case B.3
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+
+-- echo case B.4
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+
+-- echo
+-- echo Test IN as top-level predicate, and
+-- echo as non-top level for cases A.3, B.3 (the only cases with NULL result).
+-- echo
+-- echo case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+ (a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+ (a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+ NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+
+-- echo case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+# test non-top level result indirectly
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+ ((a1, b1, c1) IN (select * from t_in)) is NULL and
+ ((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+
+-- echo case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+
+-- echo case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+ (a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+ (a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+ NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+
+-- echo case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+
+-- echo case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+# test non-top level result indirectly
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+ ((a1, b1, c1) IN (select * from t_in)) is NULL and
+ ((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+
+-- echo case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+
+drop table t_out;
+drop table t_in;
+
+
+#
# Bug#27348 SET FUNCTION used in a subquery from WHERE condition
#
@@ -3506,6 +3716,231 @@ SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT
DROP TABLE t1,t2,t3;
+# -- echo #
+# -- echo # Bug#33204: INTO is allowed in subselect, causing inconsistent results
+# -- echo #
+# CREATE TABLE t1( a INT );
+# INSERT INTO t1 VALUES (1),(2);
+#
+# CREATE TABLE t2( a INT, b INT );
+#
+# --error ER_PARSE_ERROR
+# SELECT *
+# FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
+# --error ER_PARSE_ERROR
+# SELECT *
+# FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
+# --error ER_PARSE_ERROR
+# SELECT *
+# FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a INTO @var FROM t1 WHERE a = 2
+# ) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
+# ) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
+# ) t1a;
+#
+# SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
+#
+# SELECT * FROM (
+# SELECT a FROM t1 WHERE a = 2
+# UNION
+# SELECT a FROM t1 WHERE a = 2
+# ) t1a;
+#
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a FROM t1 WHERE a = 2
+# UNION
+# SELECT a FROM t1 WHERE a = 2
+# ) t1a;
+#
+# # This was not allowed previously. Possibly, it should be allowed on the future.
+# # For now, the intent is to keep the fix as non-intrusive as possible.
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a) UNION SELECT 1 a);
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a)) alias;
+# SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
+#
+# SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
+# SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a) t1a;
+# SELECT * FROM (SELECT 1 a UNION SELECT 1 a LIMIT 1) t1a;
+# SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a LIMIT 1) t1a;
+#
+# # Test of rule
+# # table_factor: '(' get_select_lex query_expression_body ')' opt_table_alias
+# # UNION should not be allowed inside the parentheses, nor should
+# # aliases after.
+# #
+# SELECT * FROM t1 JOIN (SELECT 1 UNION SELECT 1) alias ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN (t1 t1a) t1a ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 1;
+#
+# SELECT * FROM t1 JOIN (t1 t1a) ON 1;
+# SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
+#
+# SELECT * FROM (t1 t1a);
+# SELECT * FROM ((t1 t1a));
+#
+# SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
+# SELECT * FROM t1 JOIN ((SELECT 1 t1a)) alias ON 1;
+#
+# SELECT * FROM t1 JOIN (SELECT 1 a) a ON 1;
+# SELECT * FROM t1 JOIN ((SELECT 1 a)) a ON 1;
+#
+# # For the join, TABLE_LIST::select_lex == NULL
+# # Check that we handle this.
+# --error ER_PARSE_ERROR
+# SELECT * FROM (t1 JOIN (SELECT 1) t1a1 ON 1) t1a2;
+#
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 );
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
+#
+# SELECT * FROM t1 WHERE a = ( SELECT 1 );
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
+#
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 INTO @v );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 INTO DUMPFILE 'file' );
+#
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
+#
+# # Make sure context is popped when we leave the nested select
+# SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
+# SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
+#
+# # Make sure we have feature F561 (see .yy file)
+# SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
+#
+# # Make sure the parser does not allow nested UNIONs anywhere
+#
+# --error ER_PARSE_ERROR
+# SELECT 1 UNION ( SELECT 1 UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
+#
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
+# SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+#
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
+# SELECT EXISTS(SELECT 1+1);
+# --error ER_PARSE_ERROR
+# SELECT EXISTS(SELECT 1+1 INTO @test);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
+# DROP TABLE t1, t2;
#
# Bug#37460 Assertion failed:
# !table->file || table->file->inited == handler::NONE
@@ -3546,6 +3981,41 @@ DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
--echo #
+--echo # BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+--echo #
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+ (10, 10, 10, 'l'),
+ (20, 20, 20, 'l'),
+ (40, 40, 40, 'l'),
+ (41, 40, null, 'l'),
+ (50, 50, 50, 'l'),
+ (51, 50, null, 'l'),
+ (60, 60, 60, 'l'),
+ (61, 60, null, 'l'),
+ (70, 70, 70, 'l'),
+ (90, 90, null, 'l');
+insert into t2 values
+ (10, 10, 10, 'r'),
+ (30, 30, 30, 'r'),
+ (50, 50, 50, 'r'),
+ (60, 60, 60, 'r'),
+ (61, 60, null, 'r'),
+ (70, 70, 70, 'r'),
+ (71, 70, null, 'r'),
+ (80, 80, 80, 'r'),
+ (81, 80, null, 'r'),
+ (100,100,null, 'r');
+
+select *
+from t1
+where v in(select v
+ from t2
+ where t1.g=t2.g) is unknown;
+drop table t1, t2;
+
+--echo #
--echo # Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
--echo #
create table t1(id integer primary key, g integer, v integer, s char(1));
@@ -3595,6 +4065,7 @@ SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
--echo #
--echo # Bug #49512 : subquery with aggregate function crash
--echo # subselect_single_select_engine::exec()
@@ -3775,3 +4246,23 @@ select * from t2 where a=(select a from t1) and a='x';
drop table t1,t2;
--echo End of 5.1 tests
+
+--echo #
+--echo # No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+--echo #
+
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+
+select * from t3 where k in (select j from v2);
+
+drop table t1,t2,t3;
+drop view v2;
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index 8d403279a48..2a5aa1c5429 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -1,7 +1,9 @@
--disable_warnings
-drop table if exists t0, t1, t2, t3, t4, t5;
+drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
--enable_warnings
+set @save_optimizer_switch=@@optimizer_switch;
+
#
# 1. Subquery with GROUP/HAVING
#
@@ -59,9 +61,13 @@ select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
show status like 'Handler_read_rnd_next';
select ' ^ This must show 11' Z;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
# This must show trigcond:
explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
+set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
#
@@ -94,10 +100,12 @@ show status like '%Handler_read_rnd_next';
delete from t2;
insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
+set optimizer_switch='subquery_cache=off';
flush status;
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
show status like '%Handler_read%';
select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
+set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
@@ -529,6 +537,9 @@ SELECT a, MAX(b),
DROP TABLE t1, t2;
+# The next three test cases must be executed with the IN=>EXISTS strategy
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
#
# Bug #27870: crash of an equijoin query with WHERE condition containing
@@ -588,6 +599,8 @@ EXPLAIN SELECT a FROM t1 WHERE a NOT IN (SELECT a FROM t2);
DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
#
# Bug #34763: item_subselect.cc:1235:Item_in_subselect::row_value_transformer:
# Assertion failed, unexpected error message:
@@ -619,6 +632,20 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
DROP TABLE t1, t2;
#
+# Bug 2198
+#
+
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1;
+delete from t1;
+load data infile "subselect.out.file.1" into table t1;
+select * from t1;
+drop table t1;
+let $datadir=`select @@datadir`;
+--remove_file $datadir/test/subselect.out.file.1
+
+#
# Bug #37894: Assertion in init_read_record_seq in handler.h line 1444
#
@@ -692,6 +719,13 @@ DROP TABLE t1;
--echo End of 5.0 tests
+--echo #
+--echo # BUG#36896: Server crash on SELECT FROM DUAL
+--echo #
+create table t1 (a int);
+select 1 as res from dual where (1) in (select * from t1);
+drop table t1;
+
#
# BUG#36135 "void Diagnostics_area::set_eof_status(THD*): Assertion `!is_set()' failed."
#
@@ -764,6 +798,8 @@ SELECT i1, i2 FROM t1;
SELECT i1, i2 FROM t2 ORDER BY i1;
FLUSH STATUS;
+set @save_optimizer_switch2=@@optimizer_switch;
+set optimizer_switch='subquery_cache=off';
--echo
SELECT i1, i2
@@ -792,7 +828,361 @@ WHERE (i1, i2)
--echo # (read record from t1, but do not read from t2)
SHOW STATUS LIKE '%Handler_read_rnd_next';
-
+set @@optimizer_switch=@save_optimizer_switch2;
DROP TABLE t1,t2;
--echo End of 5.1 tests
+
+#
+# Test for the problem with using sj-materialization when subquery's select
+# list element SCOL is covered by equality propagation and has preceding equal
+# column PCOL which belongs to a table within the the semi-join nest: SJM-Scan
+# process should unpack column value not to SCOL but rather to PCOL, as
+# substitute_best_equal has made all conditions to refer to PCOL.
+#
+CREATE TABLE t1 (
+ a int(11) NOT NULL,
+ b int(11) NOT NULL,
+ c datetime default NULL,
+ PRIMARY KEY (a),
+ KEY idx_bc (b,c)
+);
+
+INSERT INTO t1 VALUES
+(406989,67,'2006-02-23 17:08:46'), (150078,67,'2005-10-26 11:17:45'),
+(406993,67,'2006-02-27 11:20:57'), (245655,67,'2005-12-08 15:59:08'),
+(406994,67,'2006-02-27 11:26:46'), (256,67,NULL),
+(398341,67,'2006-02-20 04:48:44'), (254,67,NULL),(1120,67,NULL),
+(406988,67,'2006-02-23 17:07:22'), (255,67,NULL),
+(398340,67,'2006-02-20 04:38:53'),(406631,67,'2006-02-23 10:49:42'),
+(245653,67,'2005-12-08 15:59:07'),(406992,67,'2006-02-24 16:47:18'),
+(245654,67,'2005-12-08 15:59:08'),(406995,67,'2006-02-28 11:55:00'),
+(127261,67,'2005-10-13 12:17:58'),(406991,67,'2006-02-24 16:42:32'),
+(245652,67,'2005-12-08 15:58:27'),(398545,67,'2006-02-20 04:53:13'),
+(154504,67,'2005-10-28 11:53:01'),(9199,67,NULL),(1,67,'2006-02-23 15:01:35'),
+(223456,67,NULL),(4101,67,NULL),(1133,67,NULL),
+(406990,67,'2006-02-23 18:01:45'),(148815,67,'2005-10-25 15:34:17'),
+(148812,67,'2005-10-25 15:30:01'),(245651,67,'2005-12-08 15:58:27'),
+(154503,67,'2005-10-28 11:52:38');
+
+create table t11 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc;
+create table t12 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc;
+create table t21 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 asc;
+create table t22 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc;
+
+update t22 set c = '2005-12-08 15:58:27' where a = 255;
+explain select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+
+drop table t1, t11, t12, t21, t22;
+
+#
+# Test sj-materialization re-execution. The test isn't meaningful (materialized
+# table stays the same across all executions) because it's hard to create a
+# dataset that would verify correct re-execution without hitting BUG#31480
+#
+create table t1(a int);
+insert into t1 values (0),(1);
+
+set @@optimizer_switch='firstmatch=off';
+explain
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t1;
+
+#
+# Test confluent duplicate weedout
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select * from t0;
+insert into t1 select a+10 from t0;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+insert into t0 values(2);
+explain select * from t1 where 2 in (select a from t0);
+select * from t1 where 2 in (select a from t0);
+set @@optimizer_switch='default,materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+select * from t1 where 2 in (select a from t0);
+set @@optimizer_switch=@save_optimizer_switch;
+
+
+#
+# FirstMatch referring to a derived table
+#
+explain select * from (select a from t0) X where a in (select a from t1);
+drop table t0, t1;
+
+#
+# LooseScan: Check if we can pick it together with range access
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2));
+insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C;
+insert into t1 select * from t1 where kp1 < 20;
+
+create table t3 (a int);
+insert into t3 select A.a + 10*B.a from t0 A, t0 B;
+
+explain select * from t3 where a in (select kp1 from t1 where kp1<20);
+
+create table t4 (pk int primary key);
+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);
+
+drop table t1, t3, t4;
+
+#
+# Test if we handle duplicate elimination temptable overflowing to disk
+#
+create table t1 (a int) as select * from t0 where a < 5;
+
+set @save_max_heap_table_size=@@max_heap_table_size;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+set @@max_heap_table_size= 16384;
+
+explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+flush status;
+select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+show status like 'Created_tmp_disk_tables';
+set @save_max_heap_table_size=@@max_heap_table_size;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1;
+
+#
+# Materialize + Scan + ref access to the subsequent table based on scanned
+# value
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a int);
+insert into t2 values (1),(2);
+create table t3 ( a int , filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
+explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
+select * from t3 where a in (select a from t2);
+
+drop table t0, t2, t3;
+
+#
+# DATETIME type checks
+#
+set @@optimizer_switch='firstmatch=off,materialization=off';
+create table t1 (a date);
+insert into t1 values ('2008-01-01'),('2008-01-01'),('2008-02-01'),('2008-02-01');
+create table t2 (a int);
+insert into t2 values (1),(2);
+create table t3 (a char(10));
+insert into t3 select * from t1;
+insert into t3 values (1),(2);
+explain select * from t2 where a in (select a from t1);
+explain select * from t2 where a in (select a from t2);
+explain select * from t2 where a in (select a from t3);
+explain select * from t1 where a in (select a from t3);
+drop table t1, t2, t3;
+create table t1 (a decimal);
+insert into t1 values (1),(2);
+explain select * from t1 where a in (select a from t1);
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+
+#
+# SJ-Materialization-scan for non-first table
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 as select * from t1;
+create table t3 (a int, b int, filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t1 A, t1 B, t1 C;
+explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
+
+#
+# Verify that straight_join modifier in parent or child prevents flattening
+#
+explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+explain select straight_join * from t2 X, t2 Y
+where X.a in (select straight_join A.a from t1 A, t1 B);
+
+#
+# SJ-Materialization scan + first table being system const table
+#
+create table t0 (a int, b int);
+insert into t0 values(1,1);
+explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
+create table t4 as select a as x, a as y from t1;
+explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
+drop table t0,t1,t2,t3,t4;
+
+#
+# LooseScan with ref access
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, filler char(100), key(a,b));
+insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B;
+create table t2 as select * from t1;
+
+explain select * from t2 where a in (select b from t1 where a=3);
+explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
+
+drop table t1,t2;
+
+#
+# Multi-column sj-materialization with lookups
+#
+create table t1 (a int, b int);
+insert into t1 select a,a from t0;
+create table t2 (a int, b int);
+insert into t2 select A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B;
+
+set @@optimizer_switch='firstmatch=off';
+explain select * from t1 where (a,b) in (select a,b from t2);
+
+# A smallish test if find_best() still works for semi-join optimization:
+set @save_optimizer_search_depth=@@optimizer_search_depth;
+set @@optimizer_search_depth=63;
+explain select * from t1 where (a,b) in (select a,b from t2);
+set @@optimizer_search_depth=@save_optimizer_search_depth;
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t0, t1, t2;
+
+
+#
+# Primitive SJ-Materialization tests for DECIMAL and DATE
+#
+create table t0 (a decimal(4,2));
+insert into t0 values (10.24), (22.11);
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+select * from t0 where a in (select a from t1);
+drop table t0, t1;
+
+create table t0(a date);
+insert into t0 values ('2008-01-01'),('2008-02-02');
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+select * from t0 where a in (select a from t1);
+drop table t0, t1;
+
+#
+# Fix a trivial crash with SJ-Materialization lookup, multiple tables in the
+# subquery, and a condition on some of inner tables but not others
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select a as a, a as b, a as c from t0 where a < 3;
+create table t2 as select a as a, a as b from t0 where a < 3;
+insert into t2 select * from t2;
+
+explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
+
+drop table t0,t1,t2;
+
+--echo
+--echo BUG#37842: Assertion in DsMrr_impl::dsmrr_init, at handler.cc:4307
+--echo
+CREATE TABLE t1 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_key` int(11) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,9),(2,3),(3,8),(4,6),(5,9),(6,5),(7,5),(8,9),(9,1),(10,10);
+SELECT `pk` FROM t1 AS OUTR WHERE `int_key` = ALL (
+ SELECT `int_key` FROM t1 AS INNR WHERE INNR . `pk` >= 9
+);
+DROP TABLE t1;
+
+--echo
+--echo BUG#40118 Crash when running Batched Key Access and requiring one match for each key
+--echo
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, key(a));
+insert into t1 select * from t0;
+alter table t1 add b int not null, add filler char(200);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+select * from t0 where t0.a in (select t1.a from t1 where t1.b=0);
+set join_cache_level=@save_join_cache_level;
+drop table t0, t1;
+
+--echo #
+--echo # BUG#32665 Query with dependent subquery is too slow
+--echo #
+create table t1 (
+ idIndividual int primary key
+);
+insert into t1 values (1),(2);
+
+create table t2 (
+ idContact int primary key,
+ contactType int,
+ idObj int
+);
+insert into t2 values (1,1,1),(2,2,2),(3,3,3);
+
+create table t3 (
+ idAddress int primary key,
+ idContact int,
+ postalStripped varchar(100)
+);
+
+insert into t3 values (1,1, 'foo'), (2,2,'bar');
+
+--echo The following must be converted to a semi-join:
+explain extended SELECT a.idIndividual FROM t1 a
+WHERE a.idIndividual IN
+ ( SELECT c.idObj FROM t3 cona
+ INNER JOIN t2 c ON c.idContact=cona.idContact
+ WHERE cona.postalStripped='T2H3B2'
+ );
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#47367 Crash in Name_resolution_context::process_error
+--echo #
+
+SET SESSION optimizer_switch = 'default,semijoin=off';
+CREATE TABLE t1 (f1 INTEGER);
+CREATE TABLE t2 LIKE t1;
+delimiter |;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+delimiter ;|
+CALL p1;
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+CALL p1;
+DROP PROCEDURE p1;
+--echo # Restore the original column list of table t2:
+ALTER TABLE t2 CHANGE COLUMN my_column f1 INT;
+
+SET SESSION optimizer_switch = 'semijoin=on';
+delimiter |;
+--echo # Recreate procedure so that we eliminate any caching effects
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+delimiter ;|
+CALL p1;
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+--error ER_BAD_FIELD_ERROR
+CALL p1;
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+
+# The following command must be the last one the file
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/subselect3_jcl6.test b/mysql-test/t/subselect3_jcl6.test
new file mode 100644
index 00000000000..6d9611f83f3
--- /dev/null
+++ b/mysql-test/t/subselect3_jcl6.test
@@ -0,0 +1,17 @@
+#
+# Run subselect3.test with BKA enabled
+#
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/subselect3.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index 41edd7f1216..4329afdd384 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -163,3 +163,272 @@ DROP TABLE t1, t2, t3, t4, t5;
--echo #
--echo # End of 5.1 tests.
--echo #
+
+--echo #
+--echo # BUG#46743 "Azalea processing correlated, aggregate SELECT
+--echo # subqueries incorrectly"
+--echo #
+
+CREATE TABLE t1 (c int);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 (d int , KEY (d)); # index is needed for bug
+INSERT INTO t2 VALUES (NULL),(NULL); # two rows needed for bug
+# we see that subquery returns 0 rows
+--echo 0 rows in subquery
+SELECT 1 AS RESULT FROM t2,t1 WHERE d = c;
+# so here it ends up as NULL
+--echo base query
+SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 ;
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 ;
+--echo first equivalent variant
+SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c ;
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c;
+--echo second equivalent variant
+# used to fail with 1242: Subquery returns more than 1 row
+SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#45928 "Differing query results depending on MRR and
+--echo # engine_condition_pushdown settings"
+--echo #
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `time_nokey` time NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ `varchar_nokey` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `varchar_key` (`varchar_key`)
+) AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (10,'00:00:00','i','i'),(11,'00:00:00','','');
+
+set @old_optimizer_switch = @@session.optimizer_switch,
+ @old_optimizer_use_mrr = @@session.optimizer_use_mrr,
+ @old_engine_condition_pushdown = @@session.engine_condition_pushdown;
+
+SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off';
+SET SESSION optimizer_use_mrr = 'force';
+SET SESSION engine_condition_pushdown = 1;
+
+ SELECT `time_nokey` G1 FROM t1 WHERE ( `varchar_nokey` , `varchar_key` ) IN (
+SELECT `varchar_nokey` , `varchar_nokey` ) AND `varchar_key` >= 'c' HAVING G1 ORDER
+BY `pk` ;
+
+set @@session.optimizer_switch = @old_optimizer_switch,
+ @@session.optimizer_use_mrr = @old_optimizer_use_mrr,
+ @@session.engine_condition_pushdown = @old_engine_condition_pushdown;
+
+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
+--echo # aware of the problem. Adding an EXPLAIN query to catch this.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1
+ (EMPNUM CHAR(3) NOT NULL,
+ EMPNAME CHAR(20),
+ GRADE DECIMAL(4),
+ CITY CHAR(15));
+
+CREATE TABLE t2
+ (PNUM CHAR(3) NOT NULL,
+ PNAME CHAR(20),
+ PTYPE CHAR(6),
+ BUDGET DECIMAL(9),
+ CITY CHAR(15));
+
+CREATE TABLE t3
+ (EMPNUM CHAR(3) NOT NULL,
+ PNUM CHAR(3) NOT NULL,
+ HOURS DECIMAL(5));
+
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET @old_join_cache_level = @@session.join_cache_level;
+SET SESSION optimizer_switch = 'firstmatch=on,loosescan=on,materialization=on,semijoin=on';
+SET SESSION join_cache_level = 1;
+
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+DROP INDEX t1_IDX ON t1;
+
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+SET SESSION optimizer_switch = @old_optimizer_switch;
+SET SESSION join_cache_level = @old_join_cache_level;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#45221 Query SELECT pk FROM C WHERE pk IN (SELECT int_key) failing
+--echo #
+
+CREATE TABLE t1 (
+ i1_key INT,
+ i2 INT,
+ i3 INT,
+ KEY i1_index (i1_key)
+);
+
+INSERT INTO t1 VALUES (9,1,2), (9,2,1);
+
+CREATE TABLE t2 (
+ pk INT NOT NULL,
+ i1 INT,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t2 VALUES (9,1);
+
+--echo # Enable Index condition pushdown
+--replace_column 1 #
+SELECT @old_icp:=@@engine_condition_pushdown;
+SET SESSION engine_condition_pushdown = 'ON';
+
+--echo
+SELECT pk
+FROM t2
+WHERE
+ pk IN (
+ SELECT i1_key
+ FROM t1
+ WHERE t1.i2 < t1.i3 XOR t2.i1 > 1
+ ORDER BY t1.i2 desc);
+
+--echo # Restore old value for Index condition pushdown
+SET SESSION engine_condition_pushdown=@old_icp;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/subselect_cache.test b/mysql-test/t/subselect_cache.test
new file mode 100644
index 00000000000..12f42aab7d6
--- /dev/null
+++ b/mysql-test/t/subselect_cache.test
@@ -0,0 +1,1616 @@
+
+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);
+create table t2 (c int, d int);
+insert into t2 values (2,3),(3,4),(5,6),(4,1);
+
+--echo *
+--echo * Test subquery as top item in different clauses
+--echo *
+--echo #single value subquery test (SELECT list)
+flush status;
+select a, (select d from t2 where b=c) from t1;
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=off';
+flush status;
+
+select a, (select d from t2 where b=c) from t1;
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+
+--echo #single value subquery test (where)
+flush status;
+select a from t1 where (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=off';
+flush status;
+
+select a from t1 where (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (having)
+flush status;
+select a from t1 where a > 0 having (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=off';
+flush status;
+
+select a from t1 where a > 0 having (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (OUTER JOIN ON)
+flush status;
+select ta.a, tb.a from t1 ta join t1 tb on (select d from t2 where tb.b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=off';
+flush status;
+
+select ta.a, tb.a from t1 ta join t1 tb on (select d from t2 where tb.b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (GROUP BY)
+flush status;
+select max(a) from t1 GROUP BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=off';
+
+flush status;
+select max(a) from t1 GROUP BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (distinct GROUP BY)
+flush status;
+select distinct max(a) from t1 GROUP BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=off';
+
+flush status;
+select distinct max(a) from t1 GROUP BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (ORDER BY)
+flush status;
+select a from t1 ORDER BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=off';
+
+flush status;
+select a from t1 ORDER BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (distinct ORDER BY)
+flush status;
+select distinct a from t1 ORDER BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=off';
+
+flush status;
+select distinct a from t1 ORDER BY (select d from t2 where b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (LEFT JOIN ON)
+flush status;
+select ta.a, tb.a from t1 ta left join t1 tb on (select d from t2 where tb.b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=off';
+flush status;
+
+select ta.a, tb.a from t1 ta left join t1 tb on (select d from t2 where tb.b=c);
+
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+
+--echo #single value subquery test (PS)
+prepare stmt1 from 'select a, (select d from t2 where b=c) + 1 from t1';
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+deallocate prepare stmt1;
+
+--echo #single value subquery test (SP)
+CREATE PROCEDURE p1() select a, (select d from t2 where b=c) + 1 from t1;
+
+call p1;
+call p1;
+
+drop procedure p1;
+
+--echo #IN subquery test
+flush status;
+
+show status like "subquery_cache%";
+select a, b , b in (select d from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+insert into t1 values (7,8),(9,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+insert into t2 values (8,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+--echo # multicolumn NOT IN with NULLs
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (b, a) not in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+set optimizer_switch='subquery_cache=on';
+select a, b, (b, a) not in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+--echo # multicolumn NOT IN with NULLs (other order)
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (a, b) not in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+set optimizer_switch='subquery_cache=on';
+select a, b, (a, b) not in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+--echo # multicolumn IN with NULLs
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (b, a) in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+set optimizer_switch='subquery_cache=on';
+select a, b, (b, a) in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+--echo # multicolumn IN with NULLs (other order)
+flush status;
+set optimizer_switch='subquery_cache=off';
+select a, b, (a, b) in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+set optimizer_switch='subquery_cache=on';
+select a, b, (a, b) in (select d, c from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+--echo #IN subquery test (PS)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+
+prepare stmt1 from 'select a, b , b in (select d from t2) as SUBS from t1';
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+
+insert into t1 values (7,8),(9,NULL);
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+
+insert into t2 values (8,NULL);
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+
+deallocate prepare stmt1;
+
+
+--echo #IN subquery test (SP)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+
+CREATE PROCEDURE p1() select a, b , b in (select d from t2) as SUBS from t1;
+
+call p1();
+show status like "subquery_cache%";
+call p1();
+show status like "subquery_cache%";
+
+insert into t1 values (7,8),(9,NULL);
+call p1();
+show status like "subquery_cache%";
+call p1();
+show status like "subquery_cache%";
+
+insert into t2 values (8,NULL);
+call p1();
+show status like "subquery_cache%";
+call p1();
+show status like "subquery_cache%";
+
+drop procedure p1;
+
+
+--echo # test of simple exists
+select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+
+--echo # test of prepared statement exists
+show status like "subquery_cache%";
+prepare stmt1 from 'select a, b , exists (select * from t2 where b=d) as SUBS from t1';
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+deallocate prepare stmt1;
+
+--echo # test of stored procedure exists
+CREATE PROCEDURE p1() select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+call p1;
+call p1;
+drop procedure p1;
+
+--echo #several subqueries
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a, b , exists (select * from t2 where b=d) as SUBSE, b in (select d from t2) as SUBSI, (select d from t2 where b=c) SUBSR from t1;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=on';
+flush status;
+select a, b , exists (select * from t2 where b=d) as SUBSE, b in (select d from t2) as SUBSI, (select d from t2 where b=c) SUBSR from t1;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+--echo #several subqueries (several levels)
+set optimizer_switch='subquery_cache=off';
+flush status;
+
+set optimizer_switch='subquery_cache=off';
+flush status;
+select a, b, (select exists (select * from t2 where b=d) from t2 where b=c) as SUNS1 from t1;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+
+set optimizer_switch='subquery_cache=on';
+flush status;
+select a, b, (select exists (select * from t2 where b=d) from t2 where b=c) as SUNS1 from t1;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+
+--echo #clean up
+drop table t1,t2;
+
+--echo test different types
+--echo #int
+CREATE TABLE t1 ( a int, b int);
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+DROP TABLE t1;
+
+--echo #char
+CREATE TABLE t1 ( a char(1), b char (1));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #decimal
+CREATE TABLE t1 ( a decimal(3,1), b decimal(3,1));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+DROP TABLE t1;
+
+--echo #date
+CREATE TABLE t1 ( a date, b date);
+INSERT INTO t1 VALUES('1000-01-01','1000-01-01'),('2000-02-01','2000-02-01'),('3000-03-03','3000-03-03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-01');
+DROP TABLE t1;
+
+--echo #datetime
+CREATE TABLE t1 ( a datetime, b datetime);
+INSERT INTO t1 VALUES('1000-01-01 01:01:01','1000-01-01 01:01:01'),('2000-02-02 02:02:02','2000-02-02 02:02:02'),('3000-03-03 03:03:03','3000-03-03 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+DROP TABLE t1;
+
+--echo #time
+CREATE TABLE t1 ( a time, b time);
+INSERT INTO t1 VALUES('01:01:01','01:01:01'),('02:02:02','02:02:02'),('03:03:03','03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '02:02:02');
+DROP TABLE t1;
+
+--echo #timestamp
+CREATE TABLE t1 ( a timestamp, b timestamp);
+INSERT INTO t1 VALUES('2000-02-02 01:01:01','2000-02-02 01:01:01'),('2000-02-02 02:02:02','2000-02-02 02:02:02'),('2000-02-02 03:03:03','2000-02-02 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+DROP TABLE t1;
+
+--echo #bit
+CREATE TABLE t1 ( a bit(20), b bit(20));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a+0 FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+DROP TABLE t1;
+
+--echo #enum
+CREATE TABLE t1 ( a enum('1','2','3'), b enum('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #set
+CREATE TABLE t1 ( a set('1','2','3'), b set('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #blob
+CREATE TABLE t1 ( a blob, b blob);
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #geometry
+CREATE TABLE t1 ( a geometry, b geometry);
+INSERT INTO t1 VALUES(POINT(1,1),POINT(1,1)),(POINT(2,2),POINT(2,2)),(POINT(3,3),POINT(3,3));
+SELECT astext(a) FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = POINT(2,2));
+DROP TABLE t1;
+
+
+--echo #uncacheable queries test (random and side effect)
+flush status;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+select a, a in (select a from t1) from t1 as ext;
+show status like "subquery_cache%";
+select a, a in (select a from t1 where -1 < rand()) from t1 as ext;
+show status like "subquery_cache%";
+select a, a in (select a from t1 where -1 < benchmark(a,100)) from t1 as ext;
+show status like "subquery_cache%";
+drop table t1;
+
+--echo #test of sql_big_tables switch and outer table reference in subquery with grouping
+set option sql_big_tables=1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
+INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3);
+SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer;
+drop table t1;
+set option sql_big_tables=0;
+
+--echo #test of function reference to outer query
+set local group_concat_max_len=400;
+create table t2 (a int, b int);
+insert into t2 values (1,1), (2,2);
+select b x, (select group_concat(x) from t2) from t2;
+drop table t2;
+set local group_concat_max_len=default;
+
+--echo #aggregate functions
+CREATE TABLE t1 (a int, b INT);
+CREATE TABLE t2 (c int, d INT);
+
+insert into t1 values (2,1), (3,1), (2,4), (3,4), (10,2), (20,2), (2,5),
+(3,5), (100,3), (200,3), (10,6), (20,6), (20,7), (100,8), (200,8);
+insert into t2 values (1,1),(3,3),(20,20);
+
+--echo aggregate function as parameter of subquery
+set optimizer_switch='subquery_cache=off';
+flush status;
+select max(a), (select max(a) from t2 where max(a)=c) from t1 group by b;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+set optimizer_switch='subquery_cache=on';
+flush status;
+select max(a), (select max(a) from t2 where max(a)=c) from t1 group by b;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+--echo argument of aggregate function as parameter of subquery (illegal use)
+set optimizer_switch='subquery_cache=off';
+flush status;
+select max(a), (select a from t2 where a=c) from t1 group by b;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='subquery_cache=on';
+flush status;
+select max(a), (select a from t2 where a=c) from t1 group by b;
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+drop table t1,t2;
+
+--echo #test of flattening subquery optimisations and cache
+create table t0 (a int);
+insert into t0 values (9),(8),(7),(6),(5),(4),(3),(2),(1),(0);
+
+create table t1(a int, b int);
+insert into t1 values
+(0,0),(1,1),(2,2),(0,0),(1,1),(2,2),(0,0),(1,1),(2,2),(0,0),(1,1),(2,2),(0,0),(1,1),(2,2);
+
+create table t2 (pk int, a int, primary key(pk));
+insert into t2 select a,a from t0;
+
+set optimizer_switch='default,semijoin=on,materialization=on,subquery_cache=on';
+flush status;
+select * from t1 where a in (select pk from t2);
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+alter table t2 drop primary key;
+set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=off';
+
+explain select * from t1 where a in (select pk from t2);
+flush status;
+select * from t1 where a in (select pk from t2);
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=on';
+
+explain select * from t1 where a in (select pk from t2);
+flush status;
+select * from t1 where a in (select pk from t2);
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+#TODO: switch off cache if materialization used
+set optimizer_switch='default,semijoin=off,materialization=on,subquery_cache=on';
+
+explain select * from t1 where a in (select pk from t2);
+flush status;
+select * from t1 where a in (select pk from t2);
+show status like "subquery_cache%";
+show status like '%Handler_read%';
+
+drop table t0,t1,t2;
+
+set optimizer_switch='default';
+
+#
+--echo #launchpad BUG#608834
+#
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,7,8,'01:27:35','v','v');
+INSERT INTO `t2` VALUES (11,1,9,'19:48:31','r','r');
+INSERT INTO `t2` VALUES (12,5,9,'00:00:00','a','a');
+INSERT INTO `t2` VALUES (13,3,186,'19:53:05','m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,'19:18:56','y','y');
+INSERT INTO `t2` VALUES (15,92,2,'10:55:12','j','j');
+INSERT INTO `t2` VALUES (16,7,3,'00:25:00','d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'12:35:47','z','z');
+INSERT INTO `t2` VALUES (18,3,133,'19:53:03','e','e');
+INSERT INTO `t2` VALUES (19,5,1,'17:53:30','h','h');
+INSERT INTO `t2` VALUES (20,1,8,'11:35:49','b','b');
+INSERT INTO `t2` VALUES (21,2,5,NULL,'s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'06:01:40','e','e');
+INSERT INTO `t2` VALUES (23,1,8,'05:45:11','j','j');
+INSERT INTO `t2` VALUES (24,0,6,'00:00:00','e','e');
+INSERT INTO `t2` VALUES (25,210,51,'00:00:00','f','f');
+INSERT INTO `t2` VALUES (26,8,4,'06:11:01','v','v');
+INSERT INTO `t2` VALUES (27,7,7,'13:02:46','x','x');
+INSERT INTO `t2` VALUES (28,5,6,'21:44:25','m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'22:43:58','c','c');
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,'11:28:45','w','w');
+INSERT INTO `t1` VALUES (2,7,9,'20:25:14','m','m');
+INSERT INTO `t1` VALUES (3,9,3,'13:47:24','m','m');
+INSERT INTO `t1` VALUES (4,7,9,'19:24:11','k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'15:59:13','r','r');
+INSERT INTO `t1` VALUES (6,2,9,'00:00:00','t','t');
+INSERT INTO `t1` VALUES (7,6,3,'15:15:04','j','j');
+INSERT INTO `t1` VALUES (8,8,8,'11:32:06','u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'18:32:33','h','h');
+INSERT INTO `t1` VALUES (10,5,53,'15:19:25','o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,'19:03:19',NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'00:39:46','k','k');
+INSERT INTO `t1` VALUES (13,188,166,NULL,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,'00:00:00','n','n');
+INSERT INTO `t1` VALUES (15,1,0,'13:12:11','t','t');
+INSERT INTO `t1` VALUES (16,1,1,'04:56:48','c','c');
+INSERT INTO `t1` VALUES (17,0,9,'19:56:05','m','m');
+INSERT INTO `t1` VALUES (18,9,5,'19:35:19','y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'05:03:03','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'18:38:59','d','d');
+
+set @@optimizer_switch='subquery_cache=off';
+
+/* cache is off */ SELECT (
+SELECT 4
+FROM DUAL ) AS field1 , SUM( DISTINCT table1 . `pk` ) AS field2 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_nokey` ) AS SUBQUERY2_field1
+FROM ( t1 AS SUBQUERY2_t1 INNER JOIN t1 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `pk` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` <= table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_int_nokey` < table1 . `pk` ) AS field3 , table1 . `col_time_key` AS field4 , table1 . `col_int_key` AS field5 , CONCAT ( table2 . `col_varchar_nokey` , table1 . `col_varchar_key` ) AS field6
+FROM ( t1 AS table1 INNER JOIN ( ( t1 AS table2 LEFT JOIN t2 AS table3 ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_nokey` ) )
+WHERE ( table2 . `col_varchar_nokey` NOT IN (
+SELECT 'd' UNION
+SELECT 'u' ) ) OR table3 . `col_varchar_nokey` <= table1 . `col_varchar_key`
+GROUP BY field1, field3, field4, field5, field6
+ORDER BY table1 . `col_int_key` , field1, field2, field3, field4, field5, field6
+;
+
+set @@optimizer_switch='subquery_cache=on';
+
+/* cache is on */ SELECT (
+SELECT 4
+FROM DUAL ) AS field1 , SUM( DISTINCT table1 . `pk` ) AS field2 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_nokey` ) AS SUBQUERY2_field1
+FROM ( t1 AS SUBQUERY2_t1 INNER JOIN t1 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `pk` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` <= table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_int_nokey` < table1 . `pk` ) AS field3 , table1 . `col_time_key` AS field4 , table1 . `col_int_key` AS field5 , CONCAT ( table2 . `col_varchar_nokey` , table1 . `col_varchar_key` ) AS field6
+FROM ( t1 AS table1 INNER JOIN ( ( t1 AS table2 LEFT JOIN t2 AS table3 ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_nokey` ) )
+WHERE ( table2 . `col_varchar_nokey` NOT IN (
+SELECT 'd' UNION
+SELECT 'u' ) ) OR table3 . `col_varchar_nokey` <= table1 . `col_varchar_key`
+GROUP BY field1, field3, field4, field5, field6
+ORDER BY table1 . `col_int_key` , field1, field2, field3, field4, field5, field6
+;
+
+drop table t1,t2;
+set @@optimizer_switch= default;
+
+#
+--echo #launchpad BUG#609045
+#
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+
+INSERT INTO `t1` VALUES (1,NULL,2,NULL,NULL,'11:28:45','11:28:45','2004-10-11 18:13:16','2004-10-11 18:13:16','w','w');
+INSERT INTO `t1` VALUES (2,7,9,'2001-09-19','2001-09-19','20:25:14','20:25:14',NULL,NULL,'m','m');
+INSERT INTO `t1` VALUES (3,9,3,'2004-09-12','2004-09-12','13:47:24','13:47:24','1900-01-01 00:00:00','1900-01-01 00:00:00','m','m');
+INSERT INTO `t1` VALUES (4,7,9,NULL,NULL,'19:24:11','19:24:11','2009-07-25 00:00:00','2009-07-25 00:00:00','k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'2002-07-19','2002-07-19','15:59:13','15:59:13',NULL,NULL,'r','r');
+INSERT INTO `t1` VALUES (6,2,9,'2002-12-16','2002-12-16','00:00:00','00:00:00','2008-07-27 00:00:00','2008-07-27 00:00:00','t','t');
+INSERT INTO `t1` VALUES (7,6,3,'2006-02-08','2006-02-08','15:15:04','15:15:04','2002-11-13 16:37:31','2002-11-13 16:37:31','j','j');
+INSERT INTO `t1` VALUES (8,8,8,'2006-08-28','2006-08-28','11:32:06','11:32:06','1900-01-01 00:00:00','1900-01-01 00:00:00','u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'2001-04-14','2001-04-14','18:32:33','18:32:33','2003-12-10 00:00:00','2003-12-10 00:00:00','h','h');
+INSERT INTO `t1` VALUES (10,5,53,'2000-01-05','2000-01-05','15:19:25','15:19:25','2001-12-21 22:38:22','2001-12-21 22:38:22','o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,'2003-12-06','2003-12-06','19:03:19','19:03:19','2008-12-13 23:16:44','2008-12-13 23:16:44',NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'1900-01-01','1900-01-01','00:39:46','00:39:46','2005-08-15 12:39:41','2005-08-15 12:39:41','k','k');
+INSERT INTO `t1` VALUES (13,188,166,'2002-11-27','2002-11-27',NULL,NULL,NULL,NULL,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,NULL,NULL,'00:00:00','00:00:00','2006-09-11 12:06:14','2006-09-11 12:06:14','n','n');
+INSERT INTO `t1` VALUES (15,1,0,'2003-05-27','2003-05-27','13:12:11','13:12:11','2007-12-15 12:39:34','2007-12-15 12:39:34','t','t');
+INSERT INTO `t1` VALUES (16,1,1,'2005-05-03','2005-05-03','04:56:48','04:56:48','2005-08-09 00:00:00','2005-08-09 00:00:00','c','c');
+INSERT INTO `t1` VALUES (17,0,9,'2001-04-18','2001-04-18','19:56:05','19:56:05','2001-09-02 22:50:02','2001-09-02 22:50:02','m','m');
+INSERT INTO `t1` VALUES (18,9,5,'2005-12-27','2005-12-27','19:35:19','19:35:19','2005-12-16 22:58:11','2005-12-16 22:58:11','y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'2004-08-20','2004-08-20','05:03:03','05:03:03','2007-04-19 00:19:53','2007-04-19 00:19:53','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'1900-01-01','1900-01-01','18:38:59','18:38:59','1900-01-01 00:00:00','1900-01-01 00:00:00','d','d');
+
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+
+INSERT INTO `t2` VALUES (10,7,8,NULL,NULL,'01:27:35','01:27:35','2002-02-26 06:14:37','2002-02-26 06:14:37','v','v');
+INSERT INTO `t2` VALUES (11,1,9,'2006-06-14','2006-06-14','19:48:31','19:48:31','1900-01-01 00:00:00','1900-01-01 00:00:00','r','r');
+INSERT INTO `t2` VALUES (12,5,9,'2002-09-12','2002-09-12','00:00:00','00:00:00','2006-12-03 09:37:26','2006-12-03 09:37:26','a','a');
+INSERT INTO `t2` VALUES (13,3,186,'2005-02-15','2005-02-15','19:53:05','19:53:05','2008-05-26 12:27:10','2008-05-26 12:27:10','m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,NULL,NULL,'19:18:56','19:18:56','2004-12-14 16:37:30','2004-12-14 16:37:30','y','y');
+INSERT INTO `t2` VALUES (15,92,2,'2008-11-04','2008-11-04','10:55:12','10:55:12','2003-02-11 21:19:41','2003-02-11 21:19:41','j','j');
+INSERT INTO `t2` VALUES (16,7,3,'2004-09-04','2004-09-04','00:25:00','00:25:00','2009-10-18 02:27:49','2009-10-18 02:27:49','d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'2006-06-05','2006-06-05','12:35:47','12:35:47','2000-09-26 07:45:57','2000-09-26 07:45:57','z','z');
+INSERT INTO `t2` VALUES (18,3,133,'1900-01-01','1900-01-01','19:53:03','19:53:03',NULL,NULL,'e','e');
+INSERT INTO `t2` VALUES (19,5,1,'1900-01-01','1900-01-01','17:53:30','17:53:30','2005-11-10 12:40:29','2005-11-10 12:40:29','h','h');
+INSERT INTO `t2` VALUES (20,1,8,'1900-01-01','1900-01-01','11:35:49','11:35:49','2009-04-25 00:00:00','2009-04-25 00:00:00','b','b');
+INSERT INTO `t2` VALUES (21,2,5,'2005-01-13','2005-01-13',NULL,NULL,'2002-11-27 00:00:00','2002-11-27 00:00:00','s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'2006-05-21','2006-05-21','06:01:40','06:01:40','2004-01-26 20:32:32','2004-01-26 20:32:32','e','e');
+INSERT INTO `t2` VALUES (23,1,8,'2003-09-08','2003-09-08','05:45:11','05:45:11','2007-10-26 11:41:40','2007-10-26 11:41:40','j','j');
+INSERT INTO `t2` VALUES (24,0,6,'2006-12-23','2006-12-23','00:00:00','00:00:00','2005-10-07 00:00:00','2005-10-07 00:00:00','e','e');
+INSERT INTO `t2` VALUES (25,210,51,'2006-10-15','2006-10-15','00:00:00','00:00:00','2000-07-15 05:00:34','2000-07-15 05:00:34','f','f');
+INSERT INTO `t2` VALUES (26,8,4,'2005-04-06','2005-04-06','06:11:01','06:11:01','2000-04-03 16:33:32','2000-04-03 16:33:32','v','v');
+INSERT INTO `t2` VALUES (27,7,7,'2008-04-07','2008-04-07','13:02:46','13:02:46',NULL,NULL,'x','x');
+INSERT INTO `t2` VALUES (28,5,6,'2006-10-10','2006-10-10','21:44:25','21:44:25','2001-04-25 01:26:12','2001-04-25 01:26:12','m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'1900-01-01','1900-01-01','22:43:58','22:43:58','2000-12-27 00:00:00','2000-12-27 00:00:00','c','c');
+
+CREATE TABLE `t3` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+
+INSERT INTO `t3` VALUES (1,1,7,'1900-01-01','1900-01-01','01:13:38','01:13:38','2005-02-05 00:00:00','2005-02-05 00:00:00','f','f');
+
+CREATE TABLE `t4` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+
+INSERT INTO `t4` VALUES (1,6,NULL,'2003-05-12','2003-05-12',NULL,NULL,'2000-09-12 00:00:00','2000-09-12 00:00:00','r','r');
+INSERT INTO `t4` VALUES (2,8,0,'2003-01-07','2003-01-07','14:34:45','14:34:45','2004-08-10 09:09:31','2004-08-10 09:09:31','c','c');
+INSERT INTO `t4` VALUES (3,6,0,NULL,NULL,'11:49:48','11:49:48','2005-03-21 04:31:40','2005-03-21 04:31:40','o','o');
+INSERT INTO `t4` VALUES (4,6,7,'2005-03-12','2005-03-12','18:12:55','18:12:55','2002-10-25 23:50:35','2002-10-25 23:50:35','c','c');
+INSERT INTO `t4` VALUES (5,3,8,'2000-08-02','2000-08-02','18:30:05','18:30:05','2001-04-01 21:14:04','2001-04-01 21:14:04','d','d');
+INSERT INTO `t4` VALUES (6,9,4,'1900-01-01','1900-01-01','14:19:30','14:19:30','2005-03-12 06:02:34','2005-03-12 06:02:34','v','v');
+INSERT INTO `t4` VALUES (7,2,6,'2006-07-06','2006-07-06','05:20:04','05:20:04','2001-05-06 14:49:12','2001-05-06 14:49:12','m','m');
+INSERT INTO `t4` VALUES (8,1,5,'2006-12-24','2006-12-24','20:29:31','20:29:31','2004-04-25 00:00:00','2004-04-25 00:00:00','j','j');
+INSERT INTO `t4` VALUES (9,8,NULL,'2004-11-16','2004-11-16','07:08:09','07:08:09','2001-03-22 18:38:43','2001-03-22 18:38:43','f','f');
+INSERT INTO `t4` VALUES (10,0,NULL,'2002-09-09','2002-09-09','14:49:14','14:49:14','2006-04-25 21:03:02','2006-04-25 21:03:02','n','n');
+INSERT INTO `t4` VALUES (11,9,8,NULL,NULL,'00:00:00','00:00:00','2009-09-07 18:40:43','2009-09-07 18:40:43','z','z');
+INSERT INTO `t4` VALUES (12,8,8,'2008-06-24','2008-06-24','09:58:06','09:58:06','2004-03-23 00:00:00','2004-03-23 00:00:00','h','h');
+INSERT INTO `t4` VALUES (13,NULL,8,'2001-04-21','2001-04-21',NULL,NULL,'2009-04-15 00:08:29','2009-04-15 00:08:29','q','q');
+INSERT INTO `t4` VALUES (14,0,1,'2003-11-22','2003-11-22','18:24:16','18:24:16','2000-04-21 00:00:00','2000-04-21 00:00:00','w','w');
+INSERT INTO `t4` VALUES (15,5,1,'2004-09-12','2004-09-12','17:39:57','17:39:57','2000-02-17 19:41:23','2000-02-17 19:41:23','z','z');
+INSERT INTO `t4` VALUES (16,1,5,'2006-06-20','2006-06-20','08:23:21','08:23:21','2003-09-20 07:38:14','2003-09-20 07:38:14','j','j');
+INSERT INTO `t4` VALUES (17,1,2,NULL,NULL,NULL,NULL,'2000-11-28 20:42:12','2000-11-28 20:42:12','a','a');
+INSERT INTO `t4` VALUES (18,6,7,'2001-11-25','2001-11-25','21:50:46','21:50:46','2005-06-12 11:13:17','2005-06-12 11:13:17','m','m');
+INSERT INTO `t4` VALUES (19,6,6,'2004-10-26','2004-10-26','12:33:17','12:33:17','1900-01-01 00:00:00','1900-01-01 00:00:00','n','n');
+INSERT INTO `t4` VALUES (20,1,4,'2005-01-19','2005-01-19','03:06:43','03:06:43','2006-02-09 20:41:06','2006-02-09 20:41:06','e','e');
+INSERT INTO `t4` VALUES (21,8,7,'2008-07-06','2008-07-06','03:46:14','03:46:14','2004-05-22 01:05:57','2004-05-22 01:05:57','u','u');
+INSERT INTO `t4` VALUES (22,1,0,'1900-01-01','1900-01-01','20:34:52','20:34:52','2004-03-04 13:46:31','2004-03-04 13:46:31','s','s');
+INSERT INTO `t4` VALUES (23,0,9,'1900-01-01','1900-01-01',NULL,NULL,'1900-01-01 00:00:00','1900-01-01 00:00:00','u','u');
+INSERT INTO `t4` VALUES (24,4,3,'2004-06-08','2004-06-08','10:41:20','10:41:20','2004-10-20 07:20:19','2004-10-20 07:20:19','r','r');
+INSERT INTO `t4` VALUES (25,9,5,'2007-02-20','2007-02-20','08:43:11','08:43:11','2006-04-17 00:00:00','2006-04-17 00:00:00','g','g');
+INSERT INTO `t4` VALUES (26,8,1,'2008-06-18','2008-06-18',NULL,NULL,'2000-10-27 00:00:00','2000-10-27 00:00:00','o','o');
+INSERT INTO `t4` VALUES (27,5,1,'2008-05-15','2008-05-15','10:17:51','10:17:51','2007-04-14 08:54:06','2007-04-14 08:54:06','w','w');
+INSERT INTO `t4` VALUES (28,9,5,'2005-10-06','2005-10-06','06:34:09','06:34:09','2008-04-12 17:03:52','2008-04-12 17:03:52','b','b');
+INSERT INTO `t4` VALUES (29,5,9,NULL,NULL,'21:22:47','21:22:47','2007-02-19 17:37:09','2007-02-19 17:37:09',NULL,NULL);
+INSERT INTO `t4` VALUES (30,NULL,2,'2006-10-12','2006-10-12','04:02:32','04:02:32','1900-01-01 00:00:00','1900-01-01 00:00:00','y','y');
+INSERT INTO `t4` VALUES (31,NULL,5,'2005-01-24','2005-01-24','02:33:14','02:33:14','2001-10-10 08:32:27','2001-10-10 08:32:27','y','y');
+INSERT INTO `t4` VALUES (32,105,248,'2009-06-27','2009-06-27','16:32:56','16:32:56',NULL,NULL,'u','u');
+INSERT INTO `t4` VALUES (33,0,0,NULL,NULL,'21:32:42','21:32:42','2001-12-16 05:31:53','2001-12-16 05:31:53','p','p');
+INSERT INTO `t4` VALUES (34,3,8,NULL,NULL,'23:04:47','23:04:47','2003-07-19 18:03:28','2003-07-19 18:03:28','s','s');
+INSERT INTO `t4` VALUES (35,1,1,'1900-01-01','1900-01-01','22:05:43','22:05:43','2001-03-27 11:44:10','2001-03-27 11:44:10','e','e');
+INSERT INTO `t4` VALUES (36,75,255,'2005-12-22','2005-12-22','02:05:45','02:05:45','2008-06-15 02:13:00','2008-06-15 02:13:00','d','d');
+INSERT INTO `t4` VALUES (37,9,9,'2005-05-03','2005-05-03','00:00:00','00:00:00','2009-03-14 21:29:56','2009-03-14 21:29:56','d','d');
+INSERT INTO `t4` VALUES (38,7,9,'2003-05-27','2003-05-27','18:09:07','18:09:07','2005-01-02 00:00:00','2005-01-02 00:00:00','c','c');
+INSERT INTO `t4` VALUES (39,NULL,3,'2006-05-25','2006-05-25','10:54:06','10:54:06','2007-07-16 04:44:07','2007-07-16 04:44:07','b','b');
+INSERT INTO `t4` VALUES (40,NULL,9,NULL,NULL,'23:15:50','23:15:50','2003-08-26 21:38:26','2003-08-26 21:38:26','t','t');
+INSERT INTO `t4` VALUES (41,4,6,'2009-01-04','2009-01-04','10:17:40','10:17:40','2004-04-19 04:18:47','2004-04-19 04:18:47',NULL,NULL);
+INSERT INTO `t4` VALUES (42,0,4,'2009-02-14','2009-02-14','03:37:09','03:37:09','2000-01-06 20:32:48','2000-01-06 20:32:48','y','y');
+INSERT INTO `t4` VALUES (43,204,60,'2003-01-16','2003-01-16','22:26:06','22:26:06','2006-06-23 13:27:17','2006-06-23 13:27:17','c','c');
+INSERT INTO `t4` VALUES (44,0,7,'1900-01-01','1900-01-01','17:10:38','17:10:38','2007-11-27 00:00:00','2007-11-27 00:00:00','d','d');
+INSERT INTO `t4` VALUES (45,9,1,'2007-06-26','2007-06-26','00:00:00','00:00:00','2002-04-03 12:06:51','2002-04-03 12:06:51','x','x');
+INSERT INTO `t4` VALUES (46,8,6,'2004-03-27','2004-03-27','17:08:49','17:08:49','2008-12-28 09:47:42','2008-12-28 09:47:42','p','p');
+INSERT INTO `t4` VALUES (47,7,4,NULL,NULL,'19:04:40','19:04:40','2002-04-04 10:07:54','2002-04-04 10:07:54','e','e');
+INSERT INTO `t4` VALUES (48,8,NULL,'2005-06-06','2005-06-06','20:53:28','20:53:28','2003-04-26 02:55:13','2003-04-26 02:55:13','g','g');
+INSERT INTO `t4` VALUES (49,NULL,8,'2003-03-02','2003-03-02','11:46:03','11:46:03',NULL,NULL,'x','x');
+INSERT INTO `t4` VALUES (50,6,0,'2004-05-13','2004-05-13',NULL,NULL,'2009-02-19 03:17:06','2009-02-19 03:17:06','s','s');
+INSERT INTO `t4` VALUES (51,5,8,'2005-09-13','2005-09-13','10:58:07','10:58:07','1900-01-01 00:00:00','1900-01-01 00:00:00','e','e');
+INSERT INTO `t4` VALUES (52,2,151,'2005-10-03','2005-10-03','00:00:00','00:00:00','2000-11-10 08:20:01','2000-11-10 08:20:01','l','l');
+INSERT INTO `t4` VALUES (53,3,7,'2005-10-14','2005-10-14','09:43:15','09:43:15','2008-02-10 00:00:00','2008-02-10 00:00:00','p','p');
+INSERT INTO `t4` VALUES (54,7,6,NULL,NULL,'21:40:32','21:40:32','1900-01-01 00:00:00','1900-01-01 00:00:00','h','h');
+INSERT INTO `t4` VALUES (55,NULL,NULL,'2005-09-16','2005-09-16','00:17:44','00:17:44',NULL,NULL,'m','m');
+INSERT INTO `t4` VALUES (56,145,23,'2005-03-10','2005-03-10','16:47:26','16:47:26','2001-02-05 02:01:50','2001-02-05 02:01:50','n','n');
+INSERT INTO `t4` VALUES (57,0,2,'2000-06-19','2000-06-19','00:00:00','00:00:00','2000-10-28 08:44:25','2000-10-28 08:44:25','v','v');
+INSERT INTO `t4` VALUES (58,1,4,'2002-11-03','2002-11-03','05:25:59','05:25:59','2005-03-20 10:53:59','2005-03-20 10:53:59','b','b');
+INSERT INTO `t4` VALUES (59,7,NULL,'2009-01-05','2009-01-05','00:00:00','00:00:00','2001-06-02 13:54:13','2001-06-02 13:54:13','x','x');
+INSERT INTO `t4` VALUES (60,3,NULL,'2003-05-22','2003-05-22','20:33:04','20:33:04','1900-01-01 00:00:00','1900-01-01 00:00:00','r','r');
+INSERT INTO `t4` VALUES (61,NULL,77,'2005-07-02','2005-07-02','00:46:12','00:46:12','2009-07-16 13:05:43','2009-07-16 13:05:43','t','t');
+INSERT INTO `t4` VALUES (62,2,NULL,'1900-01-01','1900-01-01','00:00:00','00:00:00','2009-03-26 23:16:20','2009-03-26 23:16:20','w','w');
+INSERT INTO `t4` VALUES (63,2,NULL,'2006-06-21','2006-06-21','02:13:59','02:13:59','2003-02-06 18:12:15','2003-02-06 18:12:15','w','w');
+INSERT INTO `t4` VALUES (64,2,7,NULL,NULL,'02:54:47','02:54:47','2006-06-05 03:22:51','2006-06-05 03:22:51','k','k');
+INSERT INTO `t4` VALUES (65,8,1,'2005-12-16','2005-12-16','18:13:59','18:13:59','2002-02-10 05:47:27','2002-02-10 05:47:27','a','a');
+INSERT INTO `t4` VALUES (66,6,9,'2004-11-05','2004-11-05','13:53:08','13:53:08','2001-08-01 08:50:52','2001-08-01 08:50:52','t','t');
+INSERT INTO `t4` VALUES (67,1,6,NULL,NULL,'22:21:30','22:21:30','1900-01-01 00:00:00','1900-01-01 00:00:00','z','z');
+INSERT INTO `t4` VALUES (68,NULL,2,'2004-09-14','2004-09-14','11:41:50','11:41:50',NULL,NULL,'e','e');
+INSERT INTO `t4` VALUES (69,1,3,'2002-04-06','2002-04-06','15:20:02','15:20:02','1900-01-01 00:00:00','1900-01-01 00:00:00','q','q');
+INSERT INTO `t4` VALUES (70,0,0,NULL,NULL,NULL,NULL,'2000-09-23 00:00:00','2000-09-23 00:00:00','e','e');
+INSERT INTO `t4` VALUES (71,4,NULL,'2002-11-13','2002-11-13',NULL,NULL,'2007-07-09 08:32:49','2007-07-09 08:32:49','v','v');
+INSERT INTO `t4` VALUES (72,1,6,'2006-05-27','2006-05-27','07:51:52','07:51:52','2000-01-05 00:00:00','2000-01-05 00:00:00','d','d');
+INSERT INTO `t4` VALUES (73,1,3,'2000-12-22','2000-12-22','00:00:00','00:00:00','2000-09-24 00:00:00','2000-09-24 00:00:00','u','u');
+INSERT INTO `t4` VALUES (74,27,195,'2004-02-21','2004-02-21',NULL,NULL,'2005-05-06 00:00:00','2005-05-06 00:00:00','o','o');
+INSERT INTO `t4` VALUES (75,4,5,'2009-05-15','2009-05-15',NULL,NULL,'2000-03-11 00:00:00','2000-03-11 00:00:00','b','b');
+INSERT INTO `t4` VALUES (76,6,2,'2008-12-12','2008-12-12','12:31:05','12:31:05','2001-09-02 16:17:35','2001-09-02 16:17:35','c','c');
+INSERT INTO `t4` VALUES (77,2,7,'2000-04-15','2000-04-15','00:00:00','00:00:00','2006-04-25 05:43:44','2006-04-25 05:43:44','q','q');
+INSERT INTO `t4` VALUES (78,248,25,NULL,NULL,'01:16:45','01:16:45','2009-10-25 22:04:02','2009-10-25 22:04:02',NULL,NULL);
+INSERT INTO `t4` VALUES (79,NULL,NULL,'2001-10-18','2001-10-18','20:38:54','20:38:54','2004-08-06 00:00:00','2004-08-06 00:00:00','h','h');
+INSERT INTO `t4` VALUES (80,9,0,'2008-05-25','2008-05-25','00:30:15','00:30:15','2001-11-27 05:07:57','2001-11-27 05:07:57','d','d');
+INSERT INTO `t4` VALUES (81,75,98,'2004-12-02','2004-12-02','23:46:36','23:46:36','2009-06-28 03:18:39','2009-06-28 03:18:39','w','w');
+INSERT INTO `t4` VALUES (82,2,6,'2002-02-15','2002-02-15','19:03:13','19:03:13','2000-03-12 00:00:00','2000-03-12 00:00:00','m','m');
+INSERT INTO `t4` VALUES (83,9,5,'2002-03-03','2002-03-03','10:54:27','10:54:27',NULL,NULL,'i','i');
+INSERT INTO `t4` VALUES (84,4,0,NULL,NULL,'00:25:47','00:25:47','2007-10-20 00:00:00','2007-10-20 00:00:00','w','w');
+INSERT INTO `t4` VALUES (85,0,3,'2003-01-26','2003-01-26','08:44:27','08:44:27','2009-09-27 00:00:00','2009-09-27 00:00:00','f','f');
+INSERT INTO `t4` VALUES (86,0,1,'2001-12-19','2001-12-19','08:15:38','08:15:38','2002-07-16 00:00:00','2002-07-16 00:00:00','k','k');
+INSERT INTO `t4` VALUES (87,1,1,'2001-08-07','2001-08-07','19:56:21','19:56:21','2005-02-20 00:00:00','2005-02-20 00:00:00','v','v');
+INSERT INTO `t4` VALUES (88,119,147,'2005-02-16','2005-02-16','00:00:00','00:00:00',NULL,NULL,'c','c');
+INSERT INTO `t4` VALUES (89,1,3,'2006-06-10','2006-06-10','20:50:52','20:50:52','2001-07-16 00:00:00','2001-07-16 00:00:00','y','y');
+INSERT INTO `t4` VALUES (90,7,3,NULL,NULL,'03:54:39','03:54:39','2009-05-20 21:04:12','2009-05-20 21:04:12','h','h');
+INSERT INTO `t4` VALUES (91,2,NULL,'2005-04-06','2005-04-06','23:58:17','23:58:17','2002-03-13 10:55:40','2002-03-13 10:55:40',NULL,NULL);
+INSERT INTO `t4` VALUES (92,7,2,'2003-04-27','2003-04-27','12:54:58','12:54:58','2005-07-12 00:00:00','2005-07-12 00:00:00','t','t');
+INSERT INTO `t4` VALUES (93,2,1,'2005-10-13','2005-10-13','04:02:43','04:02:43','2006-07-22 09:46:34','2006-07-22 09:46:34','l','l');
+INSERT INTO `t4` VALUES (94,6,8,'2003-10-02','2003-10-02','11:31:12','11:31:12','2001-09-01 00:00:00','2001-09-01 00:00:00','a','a');
+INSERT INTO `t4` VALUES (95,4,8,'2005-09-09','2005-09-09','20:20:04','20:20:04','2002-05-27 18:38:45','2002-05-27 18:38:45','r','r');
+INSERT INTO `t4` VALUES (96,5,8,NULL,NULL,'00:22:24','00:22:24',NULL,NULL,'s','s');
+INSERT INTO `t4` VALUES (97,7,0,'2006-02-15','2006-02-15','10:09:31','10:09:31',NULL,NULL,'z','z');
+INSERT INTO `t4` VALUES (98,1,1,'1900-01-01','1900-01-01',NULL,NULL,'2009-08-08 22:38:53','2009-08-08 22:38:53','j','j');
+INSERT INTO `t4` VALUES (99,7,8,'2003-12-24','2003-12-24','18:45:35','18:45:35',NULL,NULL,'c','c');
+INSERT INTO `t4` VALUES (100,2,5,'2001-07-26','2001-07-26','11:49:25','11:49:25','2007-04-25 05:08:49','2007-04-25 05:08:49','f','f');
+
+SET @@optimizer_switch='subquery_cache=off';
+
+/* cache is off */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+
+SET @@optimizer_switch='subquery_cache=on';
+
+/* cache is on */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+
+drop table t1,t2,t3,t4;
+set @@optimizer_switch= default;
+
+#
+--echo #launchpad BUG#609045
+#
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,7,8,'v','v');
+INSERT INTO `t2` VALUES (11,1,9,'r','r');
+INSERT INTO `t2` VALUES (12,5,9,'a','a');
+INSERT INTO `t2` VALUES (13,3,186,'m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,'y','y');
+INSERT INTO `t2` VALUES (15,92,2,'j','j');
+INSERT INTO `t2` VALUES (16,7,3,'d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'z','z');
+INSERT INTO `t2` VALUES (18,3,133,'e','e');
+INSERT INTO `t2` VALUES (19,5,1,'h','h');
+INSERT INTO `t2` VALUES (20,1,8,'b','b');
+INSERT INTO `t2` VALUES (21,2,5,'s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'e','e');
+INSERT INTO `t2` VALUES (23,1,8,'j','j');
+INSERT INTO `t2` VALUES (24,0,6,'e','e');
+INSERT INTO `t2` VALUES (25,210,51,'f','f');
+INSERT INTO `t2` VALUES (26,8,4,'v','v');
+INSERT INTO `t2` VALUES (27,7,7,'x','x');
+INSERT INTO `t2` VALUES (28,5,6,'m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'c','c');
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,'w','w');
+INSERT INTO `t1` VALUES (2,7,9,'m','m');
+INSERT INTO `t1` VALUES (3,9,3,'m','m');
+INSERT INTO `t1` VALUES (4,7,9,'k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'r','r');
+INSERT INTO `t1` VALUES (6,2,9,'t','t');
+INSERT INTO `t1` VALUES (7,6,3,'j','j');
+INSERT INTO `t1` VALUES (8,8,8,'u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'h','h');
+INSERT INTO `t1` VALUES (10,5,53,'o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'k','k');
+INSERT INTO `t1` VALUES (13,188,166,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,'n','n');
+INSERT INTO `t1` VALUES (15,1,0,'t','t');
+INSERT INTO `t1` VALUES (16,1,1,'c','c');
+INSERT INTO `t1` VALUES (17,0,9,'m','m');
+INSERT INTO `t1` VALUES (18,9,5,'y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'f','f');
+INSERT INTO `t1` VALUES (20,4,2,'d','d');
+
+SET @@optimizer_switch = 'subquery_cache=off';
+
+/* cache is off */ SELECT SUM( DISTINCT table1 .`pk` ) , (
+ SELECT MAX( `col_int_nokey` )
+ FROM t1
+ WHERE table1 .`pk` ) field3
+FROM t1 table1
+JOIN (
+ t1 table2
+ JOIN t2 table3
+ ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+)
+ON table3 .`col_varchar_key` = table2 .`col_varchar_nokey`
+GROUP BY field3 ;
+
+SET @@optimizer_switch = 'subquery_cache=on';
+
+/* cache is on */ SELECT SUM( DISTINCT table1 .`pk` ) , (
+ SELECT MAX( `col_int_nokey` )
+ FROM t1
+ WHERE table1 .`pk` ) field3
+FROM t1 table1
+JOIN (
+ t1 table2
+ JOIN t2 table3
+ ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+)
+ON table3 .`col_varchar_key` = table2 .`col_varchar_nokey`
+GROUP BY field3 ;
+
+drop table t1,t2;
+set @@optimizer_switch= default;
+
+#
+--echo #launchpad BUG#609052
+#
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,7,8,'01:27:35','v','v');
+INSERT INTO `t2` VALUES (11,1,9,'19:48:31','r','r');
+INSERT INTO `t2` VALUES (12,5,9,'00:00:00','a','a');
+INSERT INTO `t2` VALUES (13,3,186,'19:53:05','m','m');
+INSERT INTO `t2` VALUES (14,6,NULL,'19:18:56','y','y');
+INSERT INTO `t2` VALUES (15,92,2,'10:55:12','j','j');
+INSERT INTO `t2` VALUES (16,7,3,'00:25:00','d','d');
+INSERT INTO `t2` VALUES (17,NULL,0,'12:35:47','z','z');
+INSERT INTO `t2` VALUES (18,3,133,'19:53:03','e','e');
+INSERT INTO `t2` VALUES (19,5,1,'17:53:30','h','h');
+INSERT INTO `t2` VALUES (20,1,8,'11:35:49','b','b');
+INSERT INTO `t2` VALUES (21,2,5,NULL,'s','s');
+INSERT INTO `t2` VALUES (22,NULL,5,'06:01:40','e','e');
+INSERT INTO `t2` VALUES (23,1,8,'05:45:11','j','j');
+INSERT INTO `t2` VALUES (24,0,6,'00:00:00','e','e');
+INSERT INTO `t2` VALUES (25,210,51,'00:00:00','f','f');
+INSERT INTO `t2` VALUES (26,8,4,'06:11:01','v','v');
+INSERT INTO `t2` VALUES (27,7,7,'13:02:46','x','x');
+INSERT INTO `t2` VALUES (28,5,6,'21:44:25','m','m');
+INSERT INTO `t2` VALUES (29,NULL,4,'22:43:58','c','c');
+CREATE TABLE `t4` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t4` VALUES (1,6,NULL,NULL,'r','r');
+INSERT INTO `t4` VALUES (2,8,0,'14:34:45','c','c');
+INSERT INTO `t4` VALUES (3,6,0,'11:49:48','o','o');
+INSERT INTO `t4` VALUES (4,6,7,'18:12:55','c','c');
+INSERT INTO `t4` VALUES (5,3,8,'18:30:05','d','d');
+INSERT INTO `t4` VALUES (6,9,4,'14:19:30','v','v');
+INSERT INTO `t4` VALUES (7,2,6,'05:20:04','m','m');
+INSERT INTO `t4` VALUES (8,1,5,'20:29:31','j','j');
+INSERT INTO `t4` VALUES (9,8,NULL,'07:08:09','f','f');
+INSERT INTO `t4` VALUES (10,0,NULL,'14:49:14','n','n');
+INSERT INTO `t4` VALUES (11,9,8,'00:00:00','z','z');
+INSERT INTO `t4` VALUES (12,8,8,'09:58:06','h','h');
+INSERT INTO `t4` VALUES (13,NULL,8,NULL,'q','q');
+INSERT INTO `t4` VALUES (14,0,1,'18:24:16','w','w');
+INSERT INTO `t4` VALUES (15,5,1,'17:39:57','z','z');
+INSERT INTO `t4` VALUES (16,1,5,'08:23:21','j','j');
+INSERT INTO `t4` VALUES (17,1,2,NULL,'a','a');
+INSERT INTO `t4` VALUES (18,6,7,'21:50:46','m','m');
+INSERT INTO `t4` VALUES (19,6,6,'12:33:17','n','n');
+INSERT INTO `t4` VALUES (20,1,4,'03:06:43','e','e');
+INSERT INTO `t4` VALUES (21,8,7,'03:46:14','u','u');
+INSERT INTO `t4` VALUES (22,1,0,'20:34:52','s','s');
+INSERT INTO `t4` VALUES (23,0,9,NULL,'u','u');
+INSERT INTO `t4` VALUES (24,4,3,'10:41:20','r','r');
+INSERT INTO `t4` VALUES (25,9,5,'08:43:11','g','g');
+INSERT INTO `t4` VALUES (26,8,1,NULL,'o','o');
+INSERT INTO `t4` VALUES (27,5,1,'10:17:51','w','w');
+INSERT INTO `t4` VALUES (28,9,5,'06:34:09','b','b');
+INSERT INTO `t4` VALUES (29,5,9,'21:22:47',NULL,NULL);
+INSERT INTO `t4` VALUES (30,NULL,2,'04:02:32','y','y');
+INSERT INTO `t4` VALUES (31,NULL,5,'02:33:14','y','y');
+INSERT INTO `t4` VALUES (32,105,248,'16:32:56','u','u');
+INSERT INTO `t4` VALUES (33,0,0,'21:32:42','p','p');
+INSERT INTO `t4` VALUES (34,3,8,'23:04:47','s','s');
+INSERT INTO `t4` VALUES (35,1,1,'22:05:43','e','e');
+INSERT INTO `t4` VALUES (36,75,255,'02:05:45','d','d');
+INSERT INTO `t4` VALUES (37,9,9,'00:00:00','d','d');
+INSERT INTO `t4` VALUES (38,7,9,'18:09:07','c','c');
+INSERT INTO `t4` VALUES (39,NULL,3,'10:54:06','b','b');
+INSERT INTO `t4` VALUES (40,NULL,9,'23:15:50','t','t');
+INSERT INTO `t4` VALUES (41,4,6,'10:17:40',NULL,NULL);
+INSERT INTO `t4` VALUES (42,0,4,'03:37:09','y','y');
+INSERT INTO `t4` VALUES (43,204,60,'22:26:06','c','c');
+INSERT INTO `t4` VALUES (44,0,7,'17:10:38','d','d');
+INSERT INTO `t4` VALUES (45,9,1,'00:00:00','x','x');
+INSERT INTO `t4` VALUES (46,8,6,'17:08:49','p','p');
+INSERT INTO `t4` VALUES (47,7,4,'19:04:40','e','e');
+INSERT INTO `t4` VALUES (48,8,NULL,'20:53:28','g','g');
+INSERT INTO `t4` VALUES (49,NULL,8,'11:46:03','x','x');
+INSERT INTO `t4` VALUES (50,6,0,NULL,'s','s');
+INSERT INTO `t4` VALUES (51,5,8,'10:58:07','e','e');
+INSERT INTO `t4` VALUES (52,2,151,'00:00:00','l','l');
+INSERT INTO `t4` VALUES (53,3,7,'09:43:15','p','p');
+INSERT INTO `t4` VALUES (54,7,6,'21:40:32','h','h');
+INSERT INTO `t4` VALUES (55,NULL,NULL,'00:17:44','m','m');
+INSERT INTO `t4` VALUES (56,145,23,'16:47:26','n','n');
+INSERT INTO `t4` VALUES (57,0,2,'00:00:00','v','v');
+INSERT INTO `t4` VALUES (58,1,4,'05:25:59','b','b');
+INSERT INTO `t4` VALUES (59,7,NULL,'00:00:00','x','x');
+INSERT INTO `t4` VALUES (60,3,NULL,'20:33:04','r','r');
+INSERT INTO `t4` VALUES (61,NULL,77,'00:46:12','t','t');
+INSERT INTO `t4` VALUES (62,2,NULL,'00:00:00','w','w');
+INSERT INTO `t4` VALUES (63,2,NULL,'02:13:59','w','w');
+INSERT INTO `t4` VALUES (64,2,7,'02:54:47','k','k');
+INSERT INTO `t4` VALUES (65,8,1,'18:13:59','a','a');
+INSERT INTO `t4` VALUES (66,6,9,'13:53:08','t','t');
+INSERT INTO `t4` VALUES (67,1,6,'22:21:30','z','z');
+INSERT INTO `t4` VALUES (68,NULL,2,'11:41:50','e','e');
+INSERT INTO `t4` VALUES (69,1,3,'15:20:02','q','q');
+INSERT INTO `t4` VALUES (70,0,0,NULL,'e','e');
+INSERT INTO `t4` VALUES (71,4,NULL,NULL,'v','v');
+INSERT INTO `t4` VALUES (72,1,6,'07:51:52','d','d');
+INSERT INTO `t4` VALUES (73,1,3,'00:00:00','u','u');
+INSERT INTO `t4` VALUES (74,27,195,NULL,'o','o');
+INSERT INTO `t4` VALUES (75,4,5,NULL,'b','b');
+INSERT INTO `t4` VALUES (76,6,2,'12:31:05','c','c');
+INSERT INTO `t4` VALUES (77,2,7,'00:00:00','q','q');
+INSERT INTO `t4` VALUES (78,248,25,'01:16:45',NULL,NULL);
+INSERT INTO `t4` VALUES (79,NULL,NULL,'20:38:54','h','h');
+INSERT INTO `t4` VALUES (80,9,0,'00:30:15','d','d');
+INSERT INTO `t4` VALUES (81,75,98,'23:46:36','w','w');
+INSERT INTO `t4` VALUES (82,2,6,'19:03:13','m','m');
+INSERT INTO `t4` VALUES (83,9,5,'10:54:27','i','i');
+INSERT INTO `t4` VALUES (84,4,0,'00:25:47','w','w');
+INSERT INTO `t4` VALUES (85,0,3,'08:44:27','f','f');
+INSERT INTO `t4` VALUES (86,0,1,'08:15:38','k','k');
+INSERT INTO `t4` VALUES (87,1,1,'19:56:21','v','v');
+INSERT INTO `t4` VALUES (88,119,147,'00:00:00','c','c');
+INSERT INTO `t4` VALUES (89,1,3,'20:50:52','y','y');
+INSERT INTO `t4` VALUES (90,7,3,'03:54:39','h','h');
+INSERT INTO `t4` VALUES (91,2,NULL,'23:58:17',NULL,NULL);
+INSERT INTO `t4` VALUES (92,7,2,'12:54:58','t','t');
+INSERT INTO `t4` VALUES (93,2,1,'04:02:43','l','l');
+INSERT INTO `t4` VALUES (94,6,8,'11:31:12','a','a');
+INSERT INTO `t4` VALUES (95,4,8,'20:20:04','r','r');
+INSERT INTO `t4` VALUES (96,5,8,'00:22:24','s','s');
+INSERT INTO `t4` VALUES (97,7,0,'10:09:31','z','z');
+INSERT INTO `t4` VALUES (98,1,1,NULL,'j','j');
+INSERT INTO `t4` VALUES (99,7,8,'18:45:35','c','c');
+INSERT INTO `t4` VALUES (100,2,5,'11:49:25','f','f');
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,2,'11:28:45','w','w');
+INSERT INTO `t1` VALUES (2,7,9,'20:25:14','m','m');
+INSERT INTO `t1` VALUES (3,9,3,'13:47:24','m','m');
+INSERT INTO `t1` VALUES (4,7,9,'19:24:11','k','k');
+INSERT INTO `t1` VALUES (5,4,NULL,'15:59:13','r','r');
+INSERT INTO `t1` VALUES (6,2,9,'00:00:00','t','t');
+INSERT INTO `t1` VALUES (7,6,3,'15:15:04','j','j');
+INSERT INTO `t1` VALUES (8,8,8,'11:32:06','u','u');
+INSERT INTO `t1` VALUES (9,NULL,8,'18:32:33','h','h');
+INSERT INTO `t1` VALUES (10,5,53,'15:19:25','o','o');
+INSERT INTO `t1` VALUES (11,NULL,0,'19:03:19',NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,5,'00:39:46','k','k');
+INSERT INTO `t1` VALUES (13,188,166,NULL,'e','e');
+INSERT INTO `t1` VALUES (14,2,3,'00:00:00','n','n');
+INSERT INTO `t1` VALUES (15,1,0,'13:12:11','t','t');
+INSERT INTO `t1` VALUES (16,1,1,'04:56:48','c','c');
+INSERT INTO `t1` VALUES (17,0,9,'19:56:05','m','m');
+INSERT INTO `t1` VALUES (18,9,5,'19:35:19','y','y');
+INSERT INTO `t1` VALUES (19,NULL,6,'05:03:03','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'18:38:59','d','d');
+CREATE TABLE `t3` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO `t3` VALUES (10,8,8,'18:27:58',NULL,NULL);
+CREATE TABLE `t5` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO `t5` VALUES (1,1,7,'01:13:38','f','f');
+
+
+SET @@optimizer_switch='subquery_cache=off';
+
+/* cache is off */ SELECT SQL_SMALL_RESULT MAX( DISTINCT table1 . `col_varchar_key` ) AS field1 , MIN( table1 . `col_varchar_nokey` ) AS field2 , COUNT( table1 . `col_varchar_key` ) AS field3 , table2 . `col_time_key` AS field4 , COUNT( DISTINCT table2 . `col_int_key` ) AS field5 , (
+SELECT MAX( SUBQUERY1_t2 . `col_int_nokey` ) AS SUBQUERY1_field1
+FROM ( t3 AS SUBQUERY1_t1 INNER JOIN t1 AS SUBQUERY1_t2 ON (SUBQUERY1_t2 . `col_varchar_key` = SUBQUERY1_t1 . `col_varchar_nokey` ) )
+WHERE SUBQUERY1_t2 . `pk` < SUBQUERY1_t2 . `pk` ) AS field6 , COUNT( table1 . `col_varchar_nokey` ) AS field7 , COUNT( table2 . `pk` ) AS field8 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_key` ) AS SUBQUERY2_field1
+FROM ( t5 AS SUBQUERY2_t1 LEFT JOIN t2 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `col_int_key` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` != table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_varchar_nokey` >= 'o' ) AS field9 , CONCAT ( table1 . `col_varchar_key` , table2 . `col_varchar_nokey` ) AS field10
+FROM ( t4 AS table1 LEFT JOIN ( ( t1 AS table2 STRAIGHT_JOIN t1 AS table3 ON (table3 . `col_int_nokey` = table2 . `pk` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) )
+WHERE ( EXISTS (
+SELECT SUBQUERY3_t1 . `pk` AS SUBQUERY3_field1
+FROM ( t4 AS SUBQUERY3_t1 INNER JOIN t4 AS SUBQUERY3_t2 ON (SUBQUERY3_t2 . `col_varchar_key` = SUBQUERY3_t1 . `col_varchar_key` ) )
+WHERE SUBQUERY3_t1 . `col_int_key` > table3 . `pk` AND SUBQUERY3_t1 . `pk` != table3 . `pk` ) ) AND ( table1 . `pk` > 116 AND table1 . `pk` < ( 116 + 175 ) OR table1 . `pk` IN (251) ) OR table1 . `col_int_nokey` = table1 . `col_int_nokey`
+GROUP BY field4, field6, field9, field10
+HAVING field10 = 'c'
+;
+
+SET @@optimizer_switch='subquery_cache=on';
+
+/* cache is on */ SELECT SQL_SMALL_RESULT MAX( DISTINCT table1 . `col_varchar_key` ) AS field1 , MIN( table1 . `col_varchar_nokey` ) AS field2 , COUNT( table1 . `col_varchar_key` ) AS field3 , table2 . `col_time_key` AS field4 , COUNT( DISTINCT table2 . `col_int_key` ) AS field5 , (
+SELECT MAX( SUBQUERY1_t2 . `col_int_nokey` ) AS SUBQUERY1_field1
+FROM ( t3 AS SUBQUERY1_t1 INNER JOIN t1 AS SUBQUERY1_t2 ON (SUBQUERY1_t2 . `col_varchar_key` = SUBQUERY1_t1 . `col_varchar_nokey` ) )
+WHERE SUBQUERY1_t2 . `pk` < SUBQUERY1_t2 . `pk` ) AS field6 , COUNT( table1 . `col_varchar_nokey` ) AS field7 , COUNT( table2 . `pk` ) AS field8 , (
+SELECT MAX( SUBQUERY2_t1 . `col_int_key` ) AS SUBQUERY2_field1
+FROM ( t5 AS SUBQUERY2_t1 LEFT JOIN t2 AS SUBQUERY2_t2 ON (SUBQUERY2_t2 . `col_int_key` = SUBQUERY2_t1 . `col_int_key` ) )
+WHERE SUBQUERY2_t2 . `col_varchar_nokey` != table1 . `col_varchar_key` OR SUBQUERY2_t1 . `col_varchar_nokey` >= 'o' ) AS field9 , CONCAT ( table1 . `col_varchar_key` , table2 . `col_varchar_nokey` ) AS field10
+FROM ( t4 AS table1 LEFT JOIN ( ( t1 AS table2 STRAIGHT_JOIN t1 AS table3 ON (table3 . `col_int_nokey` = table2 . `pk` ) ) ) ON (table3 . `col_varchar_key` = table2 . `col_varchar_key` ) )
+WHERE ( EXISTS (
+SELECT SUBQUERY3_t1 . `pk` AS SUBQUERY3_field1
+FROM ( t4 AS SUBQUERY3_t1 INNER JOIN t4 AS SUBQUERY3_t2 ON (SUBQUERY3_t2 . `col_varchar_key` = SUBQUERY3_t1 . `col_varchar_key` ) )
+WHERE SUBQUERY3_t1 . `col_int_key` > table3 . `pk` AND SUBQUERY3_t1 . `pk` != table3 . `pk` ) ) AND ( table1 . `pk` > 116 AND table1 . `pk` < ( 116 + 175 ) OR table1 . `pk` IN (251) ) OR table1 . `col_int_nokey` = table1 . `col_int_nokey`
+GROUP BY field4, field6, field9, field10
+HAVING field10 = 'c'
+;
+
+drop table t1,t2,t3,t4,t5;
+set @@optimizer_switch= default;
+
+
+#
+--echo #launchpad BUG#609043
+#
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (19,NULL,6,'2004-08-20','2004-08-20','05:03:03','05:03:03','2007-04-19 00:19:53','2007-04-19 00:19:53','f','f');
+INSERT INTO `t1` VALUES (20,4,2,'1900-01-01','1900-01-01','18:38:59','18:38:59','1900-01-01 00:00:00','1900-01-01 00:00:00','d','d');
+
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+
+CREATE TABLE `t3` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+
+CREATE TABLE `t4` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t4` VALUES (100,2,5,'2001-07-26','2001-07-26','11:49:25','11:49:25','2007-04-25 05:08:49','2007-04-25 05:08:49','f','f');
+
+SET @@optimizer_switch = 'subquery_cache=off';
+
+/* cache is off */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+
+SET @@optimizer_switch = 'subquery_cache=on';
+
+/* cache is on */ SELECT COUNT( DISTINCT table2 .`col_int_key` ) , (
+SELECT SUBQUERY2_t1 .`col_int_key`
+FROM t3 SUBQUERY2_t1 JOIN t2 ON SUBQUERY2_t1 .`col_int_key`
+WHERE table1 .`col_varchar_key` ) , table2 .`col_varchar_nokey` field10
+FROM t4 table1 JOIN ( t1 table2 STRAIGHT_JOIN t1 table3 ON table2 .`pk` ) ON table3 .`col_varchar_key` = table2 .`col_varchar_key`
+GROUP BY field10 ;
+
+drop table t1,t2,t3,t4;
+set @@optimizer_switch= default;
+
+#
+--echo #launchpad BUG#611625
+#
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,NULL,'w');
+INSERT INTO `t1` VALUES (2,7,'m');
+INSERT INTO `t1` VALUES (3,9,'m');
+INSERT INTO `t1` VALUES (4,7,'k');
+INSERT INTO `t1` VALUES (5,4,'r');
+INSERT INTO `t1` VALUES (6,2,'t');
+INSERT INTO `t1` VALUES (7,6,'j');
+INSERT INTO `t1` VALUES (8,8,'u');
+INSERT INTO `t1` VALUES (9,NULL,'h');
+INSERT INTO `t1` VALUES (10,5,'o');
+INSERT INTO `t1` VALUES (11,NULL,NULL);
+INSERT INTO `t1` VALUES (12,6,'k');
+INSERT INTO `t1` VALUES (13,188,'e');
+INSERT INTO `t1` VALUES (14,2,'n');
+INSERT INTO `t1` VALUES (15,1,'t');
+INSERT INTO `t1` VALUES (16,1,'c');
+INSERT INTO `t1` VALUES (17,0,'m');
+INSERT INTO `t1` VALUES (18,9,'y');
+INSERT INTO `t1` VALUES (19,NULL,'f');
+INSERT INTO `t1` VALUES (20,4,'d');
+CREATE TABLE `t3` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t3` VALUES (1,6,'r');
+INSERT INTO `t3` VALUES (2,8,'c');
+INSERT INTO `t3` VALUES (3,6,'o');
+INSERT INTO `t3` VALUES (4,6,'c');
+INSERT INTO `t3` VALUES (5,3,'d');
+INSERT INTO `t3` VALUES (6,9,'v');
+INSERT INTO `t3` VALUES (7,2,'m');
+INSERT INTO `t3` VALUES (8,1,'j');
+INSERT INTO `t3` VALUES (9,8,'f');
+INSERT INTO `t3` VALUES (10,0,'n');
+INSERT INTO `t3` VALUES (11,9,'z');
+INSERT INTO `t3` VALUES (12,8,'h');
+INSERT INTO `t3` VALUES (13,NULL,'q');
+INSERT INTO `t3` VALUES (14,0,'w');
+INSERT INTO `t3` VALUES (15,5,'z');
+INSERT INTO `t3` VALUES (16,1,'j');
+INSERT INTO `t3` VALUES (17,1,'a');
+INSERT INTO `t3` VALUES (18,6,'m');
+INSERT INTO `t3` VALUES (19,6,'n');
+INSERT INTO `t3` VALUES (20,1,'e');
+INSERT INTO `t3` VALUES (21,8,'u');
+INSERT INTO `t3` VALUES (22,1,'s');
+INSERT INTO `t3` VALUES (23,0,'u');
+INSERT INTO `t3` VALUES (24,4,'r');
+INSERT INTO `t3` VALUES (25,9,'g');
+INSERT INTO `t3` VALUES (26,8,'o');
+INSERT INTO `t3` VALUES (27,5,'w');
+INSERT INTO `t3` VALUES (28,9,'b');
+INSERT INTO `t3` VALUES (29,5,NULL);
+INSERT INTO `t3` VALUES (30,NULL,'y');
+INSERT INTO `t3` VALUES (31,NULL,'y');
+INSERT INTO `t3` VALUES (32,105,'u');
+INSERT INTO `t3` VALUES (33,0,'p');
+INSERT INTO `t3` VALUES (34,3,'s');
+INSERT INTO `t3` VALUES (35,1,'e');
+INSERT INTO `t3` VALUES (36,75,'d');
+INSERT INTO `t3` VALUES (37,9,'d');
+INSERT INTO `t3` VALUES (38,7,'c');
+INSERT INTO `t3` VALUES (39,NULL,'b');
+INSERT INTO `t3` VALUES (40,NULL,'t');
+INSERT INTO `t3` VALUES (41,4,NULL);
+INSERT INTO `t3` VALUES (42,0,'y');
+INSERT INTO `t3` VALUES (43,204,'c');
+INSERT INTO `t3` VALUES (44,0,'d');
+INSERT INTO `t3` VALUES (45,9,'x');
+INSERT INTO `t3` VALUES (46,8,'p');
+INSERT INTO `t3` VALUES (47,7,'e');
+INSERT INTO `t3` VALUES (48,8,'g');
+INSERT INTO `t3` VALUES (49,NULL,'x');
+INSERT INTO `t3` VALUES (50,6,'s');
+INSERT INTO `t3` VALUES (51,5,'e');
+INSERT INTO `t3` VALUES (52,2,'l');
+INSERT INTO `t3` VALUES (53,3,'p');
+INSERT INTO `t3` VALUES (54,7,'h');
+INSERT INTO `t3` VALUES (55,NULL,'m');
+INSERT INTO `t3` VALUES (56,145,'n');
+INSERT INTO `t3` VALUES (57,0,'v');
+INSERT INTO `t3` VALUES (58,1,'b');
+INSERT INTO `t3` VALUES (59,7,'x');
+INSERT INTO `t3` VALUES (60,3,'r');
+INSERT INTO `t3` VALUES (61,NULL,'t');
+INSERT INTO `t3` VALUES (62,2,'w');
+INSERT INTO `t3` VALUES (63,2,'w');
+INSERT INTO `t3` VALUES (64,2,'k');
+INSERT INTO `t3` VALUES (65,8,'a');
+INSERT INTO `t3` VALUES (66,6,'t');
+INSERT INTO `t3` VALUES (67,1,'z');
+INSERT INTO `t3` VALUES (68,NULL,'e');
+INSERT INTO `t3` VALUES (69,1,'q');
+INSERT INTO `t3` VALUES (70,0,'e');
+INSERT INTO `t3` VALUES (71,4,'v');
+INSERT INTO `t3` VALUES (72,1,'d');
+INSERT INTO `t3` VALUES (73,1,'u');
+INSERT INTO `t3` VALUES (74,27,'o');
+INSERT INTO `t3` VALUES (75,4,'b');
+INSERT INTO `t3` VALUES (76,6,'c');
+INSERT INTO `t3` VALUES (77,2,'q');
+INSERT INTO `t3` VALUES (78,248,NULL);
+INSERT INTO `t3` VALUES (79,NULL,'h');
+INSERT INTO `t3` VALUES (80,9,'d');
+INSERT INTO `t3` VALUES (81,75,'w');
+INSERT INTO `t3` VALUES (82,2,'m');
+INSERT INTO `t3` VALUES (83,9,'i');
+INSERT INTO `t3` VALUES (84,4,'w');
+INSERT INTO `t3` VALUES (85,0,'f');
+INSERT INTO `t3` VALUES (86,0,'k');
+INSERT INTO `t3` VALUES (87,1,'v');
+INSERT INTO `t3` VALUES (88,119,'c');
+INSERT INTO `t3` VALUES (89,1,'y');
+INSERT INTO `t3` VALUES (90,7,'h');
+INSERT INTO `t3` VALUES (91,2,NULL);
+INSERT INTO `t3` VALUES (92,7,'t');
+INSERT INTO `t3` VALUES (93,2,'l');
+INSERT INTO `t3` VALUES (94,6,'a');
+INSERT INTO `t3` VALUES (95,4,'r');
+INSERT INTO `t3` VALUES (96,5,'s');
+INSERT INTO `t3` VALUES (97,7,'z');
+INSERT INTO `t3` VALUES (98,1,'j');
+INSERT INTO `t3` VALUES (99,7,'c');
+INSERT INTO `t3` VALUES (100,2,'f');
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (10,8,NULL);
+
+set optimizer_switch='subquery_cache=off';
+
+SELECT (
+SELECT `col_int_nokey`
+FROM t3
+WHERE table1 .`col_varchar_nokey` ) field13
+FROM t2 table1 JOIN t1 table2 ON table2 .`pk`
+ORDER BY field13;
+
+set optimizer_switch='subquery_cache=on';
+
+SELECT
+ (SELECT `col_int_nokey`
+ FROM t3
+ WHERE table1 .`col_varchar_nokey` ) field13
+FROM t2 table1 JOIN t1 table2 ON table2 .`pk`
+ORDER BY field13;
+
+drop table t1,t2,t3;
+set @@optimizer_switch= default;
+
+#
+--echo # LP BUG#615760 (part 1: double transformation)
+#
+create table t1 (a int);
+insert into t1 values (1),(2);
+create table t2 (b int);
+insert into t2 values (1),(2);
+set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=on';
+
+explain extended
+select * from t1 where a in (select b from t2);
+
+drop table t1,t2;
+set @@optimizer_switch= default;
+
+#
+--echo # LP BUG#615760 (part 2: incorrect heap table index flags)
+#
+SET SESSION optimizer_switch = 'index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_condition_pushdown=off,firstmatch=off,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=on';
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
+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,3,186,'m','m');
+INSERT INTO `t1` VALUES (14,6,NULL,'y','y');
+INSERT INTO `t1` VALUES (15,92,2,'j','j');
+INSERT INTO `t1` VALUES (16,7,3,'d','d');
+INSERT INTO `t1` VALUES (17,NULL,0,'z','z');
+INSERT INTO `t1` VALUES (18,3,133,'e','e');
+INSERT INTO `t1` VALUES (19,5,1,'h','h');
+INSERT INTO `t1` VALUES (20,1,8,'b','b');
+INSERT INTO `t1` VALUES (21,2,5,'s','s');
+INSERT INTO `t1` VALUES (22,NULL,5,'e','e');
+INSERT INTO `t1` VALUES (23,1,8,'j','j');
+INSERT INTO `t1` VALUES (24,0,6,'e','e');
+INSERT INTO `t1` VALUES (25,210,51,'f','f');
+INSERT INTO `t1` VALUES (26,8,4,'v','v');
+INSERT INTO `t1` VALUES (27,7,7,'x','x');
+INSERT INTO `t1` VALUES (28,5,6,'m','m');
+INSERT INTO `t1` VALUES (29,NULL,4,'c','c');
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (1,NULL,2,'w','w');
+INSERT INTO `t2` VALUES (2,7,9,'m','m');
+INSERT INTO `t2` VALUES (3,9,3,'m','m');
+INSERT INTO `t2` VALUES (4,7,9,'k','k');
+INSERT INTO `t2` VALUES (5,4,NULL,'r','r');
+INSERT INTO `t2` VALUES (6,2,9,'t','t');
+INSERT INTO `t2` VALUES (7,6,3,'j','j');
+INSERT INTO `t2` VALUES (8,8,8,'u','u');
+INSERT INTO `t2` VALUES (9,NULL,8,'h','h');
+INSERT INTO `t2` VALUES (10,5,53,'o','o');
+INSERT INTO `t2` VALUES (11,NULL,0,NULL,NULL);
+INSERT INTO `t2` VALUES (12,6,5,'k','k');
+INSERT INTO `t2` VALUES (13,188,166,'e','e');
+INSERT INTO `t2` VALUES (14,2,3,'n','n');
+INSERT INTO `t2` VALUES (15,1,0,'t','t');
+INSERT INTO `t2` VALUES (16,1,1,'c','c');
+INSERT INTO `t2` VALUES (17,0,9,'m','m');
+INSERT INTO `t2` VALUES (18,9,5,'y','y');
+INSERT INTO `t2` VALUES (19,NULL,6,'f','f');
+INSERT INTO `t2` VALUES (20,4,2,'d','d');
+
+# Here we just need plenty of different parameters to overflow
+# temporary heap table of expression cache
+SELECT table1 .`col_varchar_nokey`
+FROM t2 table1 RIGHT JOIN t1 LEFT JOIN (
+SELECT SUBQUERY1_t2 .*
+FROM t1 SUBQUERY1_t1 LEFT JOIN t2 SUBQUERY1_t2 ON SUBQUERY1_t2 .`col_int_key` = SUBQUERY1_t1 .`col_int_nokey` ) table3 STRAIGHT_JOIN ( (
+SELECT *
+FROM t1 ) table4 JOIN ( t1 table5 JOIN t2 table6 ON table5 .`pk` ) ON table5 .`col_varchar_nokey` ) ON table6 .`pk` = table5 .`col_int_key` ON table5 .`col_varchar_nokey` ON table5 .`col_varchar_key`
+WHERE table3 .`col_varchar_key` IN (
+SELECT `col_varchar_key`
+FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
+
+drop table t1,t2;
+set @@optimizer_switch= default;
+
+#
+--echo # LP BUG#615378 (incorrect NULL result returning in Item_cache)
+#
+# if bug present here will be valgrind warnings (due to attempt to process
+# uninialized decimal value) but the result will be correct (due to
+# Item::null_value)
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_varchar_key` (`col_varchar_key`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (10,'v');
+INSERT INTO `t1` VALUES (11,'r');
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_varchar_key` (`col_varchar_key`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `t2` VALUES (1,'r');
+INSERT INTO `t2` VALUES (2,'c');
+CREATE TABLE `t3` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_varchar_key` (`col_varchar_key`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `t3` VALUES (1,'w');
+
+# We may get warnings about 'h' not beeing a double here
+--disable_warnings
+SELECT SUM( DISTINCT table2 . `pk` ) AS field2 ,
+(SELECT SUM( SUBQUERY1_t2 . `pk` ) AS SUBQUERY1_field1
+ FROM t2 AS SUBQUERY1_t2 STRAIGHT_JOIN
+ t3 AS SUBQUERY1_t3 ON (SUBQUERY1_t3 . `pk` = SUBQUERY1_t2 . `pk` )
+ WHERE table1 . `col_varchar_key` ) AS field3
+FROM ( t1 AS table1 LEFT JOIN
+ ( t2 AS table2 STRAIGHT_JOIN
+ t3 AS table3 ON (table3 . `pk` = table2 . `pk` ) )
+ ON (table3 . `col_varchar_key` = table1 . `col_varchar_key` ) )
+WHERE ( table1 . `pk` < 5 ) OR ( table1 . `col_varchar_key` IS NOT NULL)
+GROUP BY field3
+HAVING (field3 <= 'h' AND field2 != 4) ;
+--enable_warnings
+drop tables t1, t2, t3;
diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test
new file mode 100644
index 00000000000..81a33c95424
--- /dev/null
+++ b/mysql-test/t/subselect_mat.test
@@ -0,0 +1,990 @@
+#
+# Hash semi-join regression tests
+# (WL#1110: Subquery optimization: materialization)
+#
+
+--disable_warnings
+drop table if exists t1, t2, t3, t1i, t2i, t3i;
+drop view if exists v1, v2, v1m, v2m;
+--enable_warnings
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+create table t3 (c1 char(8), c2 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values ('1 - 02', '2 - 02');
+
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 03', '2 - 03');
+
+insert into t3 values ('1 - 01', '2 - 01');
+insert into t3 values ('1 - 02', '2 - 02');
+insert into t3 values ('1 - 03', '2 - 03');
+insert into t3 values ('1 - 04', '2 - 04');
+
+# Indexed columns
+create table t1i (a1 char(8), a2 char(8));
+create table t2i (b1 char(8), b2 char(8));
+create table t3i (c1 char(8), c2 char(8));
+create index it1i1 on t1i (a1);
+create index it1i2 on t1i (a2);
+create index it1i3 on t1i (a1, a2);
+
+create index it2i1 on t2i (b1);
+create index it2i2 on t2i (b2);
+create index it2i3 on t2i (b1, b2);
+
+create index it3i1 on t3i (c1);
+create index it3i2 on t3i (c2);
+create index it3i3 on t3i (c1, c2);
+
+insert into t1i select * from t1;
+insert into t2i select * from t2;
+insert into t3i select * from t3;
+
+# force the use of materialization
+set @@optimizer_switch='semijoin=off';
+
+/******************************************************************************
+* Simple tests.
+******************************************************************************/
+# non-indexed nullable fields
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+
+# indexed columns
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+
+# BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable.
+explain extended
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+
+prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st1;
+execute st1;
+prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st2;
+execute st2;
+
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+-- error 1235
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
+
+# test re-optimization/re-execution with different execution methods
+# prepare once, exec with different modes
+set @@optimizer_switch='default,semijoin=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch='default,materialization=off';
+execute st1;
+set @@optimizer_switch='default,semijoin=off';
+execute st1;
+
+set @@optimizer_switch='default,materialization=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch='default,semijoin=off';
+execute st1;
+set @@optimizer_switch='default,materialization=off';
+execute st1;
+set @@optimizer_switch='default,semijoin=off';
+
+# materialize the result of ORDER BY
+# non-indexed fields
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+# indexed fields
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+
+/******************************************************************************
+* Views, UNIONs, several levels of nesting.
+******************************************************************************/
+# materialize the result of subquery over temp-table view
+
+create algorithm=merge view v1 as
+select b1, c2 from t2, t3 where b2 > c2;
+
+create algorithm=merge view v2 as
+select b1, c2 from t2, t3 group by b2, c2;
+
+create algorithm=temptable view v1m as
+select b1, c2 from t2, t3 where b2 > c2;
+
+create algorithm=temptable view v2m as
+select b1, c2 from t2, t3 group by b2, c2;
+
+select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null);
+select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
+
+select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
+select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
+
+drop view v1, v2, v1m, v2m;
+
+# nested subqueries, views
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+explain extended
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 where c2 LIKE '%02') or
+ b2 in (select c2 from t3 where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where 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
+ b2 in (select c2 from t3 where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+# as above with correlated innermost subquery
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 t3a where c1 = a1) or
+ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3 t3c
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '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
+ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3 t3c
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+
+# multiple levels of nesting subqueries, unions
+explain extended
+(select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 where c2 LIKE '%02') or
+ b2 in (select c2 from t3 where c2 LIKE '%03')
+ group by b1, b2) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
+UNION
+(select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where 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
+ b2 in (select c2 from t3 where c2 LIKE '%03')
+ group by b1, b2) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
+UNION
+(select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
+
+
+# UNION of subqueries as a subquery (thus it is not computed via materialization)
+explain extended
+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
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '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
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+# as above, with a join conditon between the outer references
+explain extended
+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
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
+ a1 = c1;
+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
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
+ a1 = c1;
+
+
+/******************************************************************************
+* Negative tests, where materialization should not be applied.
+******************************************************************************/
+# UNION in a subquery
+explain extended
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+
+# correlation
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 t3a where c1 = a1) or
+ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3 t3c
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2));
+
+# subquery has no tables
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+
+
+/******************************************************************************
+* Subqueries in other uncovered clauses.
+******************************************************************************/
+
+/* SELECT clause */
+select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
+
+/* GROUP BY clause */
+create table columns (col int key);
+insert into columns values (1), (2);
+
+explain extended
+select * from t1 group by (select col from columns limit 1);
+select * from t1 group by (select col from columns limit 1);
+
+explain extended
+select * from t1 group by (a1 in (select col from columns));
+select * from t1 group by (a1 in (select col from columns));
+
+/* ORDER BY clause */
+explain extended
+select * from t1 order by (select col from columns limit 1);
+select * from t1 order by (select col from columns limit 1);
+
+/******************************************************************************
+* Column types/sizes that affect materialization.
+******************************************************************************/
+
+/*
+ Test that BLOBs are not materialized (except when arguments of some functions).
+*/
+# force materialization to be always considered
+set @@optimizer_switch='semijoin=off';
+set @prefix_len = 6;
+
+# BLOB == 16 (small blobs that could be stored in HEAP tables)
+set @blob_len = 16;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_16 (a1 blob(16), a2 blob(16));
+create table t2_16 (b1 blob(16), b2 blob(16));
+create table t3_16 (c1 blob(16), c2 blob(16));
+
+insert into t1_16 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_16 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_16 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_16 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_16 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_16 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_16 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_16 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_16 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_16 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
+
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+# BLOB column at the second (intermediate) level of nesting
+explain extended
+select * from t1
+where concat(a1,'x') IN
+ (select left(a1,8) from t1_16
+ where (a1, a2) IN
+ (select t2_16.b1, t2_16.b2 from t2_16, t2
+ where t2.b2 = substring(t2_16.b2,1,6) and
+ t2.b1 IN (select c1 from t3 where c2 > '0')));
+
+
+drop table t1_16, t2_16, t3_16;
+
+
+# BLOB == 512 (CONVERT_IF_BIGGER_TO_BLOB == 512)
+set @blob_len = 512;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_512 (a1 blob(512), a2 blob(512));
+create table t2_512 (b1 blob(512), b2 blob(512));
+create table t3_512 (c1 blob(512), c2 blob(512));
+
+insert into t1_512 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_512 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_512 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_512 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_512 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_512 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_512 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_512 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_512 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_512 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
+
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+drop table t1_512, t2_512, t3_512;
+
+
+# BLOB == 1024 (group_concat_max_len == 1024)
+set @blob_len = 1024;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_1024 (a1 blob(1024), a2 blob(1024));
+create table t2_1024 (b1 blob(1024), b2 blob(1024));
+create table t3_1024 (c1 blob(1024), c2 blob(1024));
+
+insert into t1_1024 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_1024 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_1024 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_1024 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_1024 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1024 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_1024 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_1024 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_1024 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1024 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+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');
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+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);
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1024)
+
+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);
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+
+drop table t1_1024, t2_1024, t3_1024;
+
+
+# BLOB == 1025
+set @blob_len = 1025;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_1025 (a1 blob(1025), a2 blob(1025));
+create table t2_1025 (b1 blob(1025), b2 blob(1025));
+create table t3_1025 (c1 blob(1025), c2 blob(1025));
+
+insert into t1_1025 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_1025 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_1025 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_1025 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_1025 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1025 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_1025 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_1025 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_1025 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1025 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+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');
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+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);
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1025)
+
+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);
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+
+drop table t1_1025, t2_1025, t3_1025;
+
+# test for BIT fields
+create table t1bit (a1 bit(3), a2 bit(3));
+create table t2bit (b1 bit(3), b2 bit(3));
+
+insert into t1bit values (b'000', b'100');
+insert into t1bit values (b'001', b'101');
+insert into t1bit values (b'010', b'110');
+
+insert into t2bit values (b'001', b'101');
+insert into t2bit values (b'010', b'110');
+insert into t2bit values (b'110', b'111');
+
+set @@optimizer_switch='semijoin=off';
+
+explain extended select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+
+select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+
+drop table t1bit, t2bit;
+
+# test mixture of BIT and BLOB
+create table t1bb (a1 bit(3), a2 blob(3));
+create table t2bb (b1 bit(3), b2 blob(3));
+
+insert into t1bb values (b'000', '100');
+insert into t1bb values (b'001', '101');
+insert into t1bb values (b'010', '110');
+
+insert into t2bb values (b'001', '101');
+insert into t2bb values (b'010', '110');
+insert into t2bb values (b'110', '111');
+
+explain extended select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+
+drop table t1bb, t2bb;
+drop table t1, t2, t3, t1i, t2i, t3i, columns;
+
+/******************************************************************************
+* Test the cache of the left operand of IN.
+******************************************************************************/
+set @@optimizer_switch='semijoin=off';
+
+# Test that default values of Cached_item are not used for comparison
+create table t1 (s1 int);
+create table t2 (s2 int);
+insert into t1 values (5),(1),(0);
+insert into t2 values (0), (1);
+select s2 from t2 where s2 in (select s1 from t1);
+drop table t1, t2;
+
+create table t1 (a int not null, b int not null);
+create table t2 (c int not null, d int not null);
+create table t3 (e int not null);
+
+# the first outer row has no matching inner row
+insert into t1 values (1,10);
+insert into t1 values (1,20);
+insert into t1 values (2,10);
+insert into t1 values (2,20);
+insert into t1 values (2,30);
+insert into t1 values (3,20);
+insert into t1 values (4,40);
+
+insert into t2 values (2,10);
+insert into t2 values (2,20);
+insert into t2 values (2,40);
+insert into t2 values (3,20);
+insert into t2 values (4,10);
+insert into t2 values (5,10);
+
+insert into t3 values (10);
+insert into t3 values (10);
+insert into t3 values (20);
+insert into t3 values (30);
+
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+select a from t1 where a in (select c from t2 where d >= 20);
+
+create index it1a on t1(a);
+
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+select a from t1 where a in (select c from t2 where d >= 20);
+
+# the first outer row has a matching inner row
+insert into t2 values (1,10);
+
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+select a from t1 where a in (select c from t2 where d >= 20);
+
+# cacheing for IN predicates inside a having clause - here the cached
+# items are changed to point to temporary tables.
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+
+# create an index that can be used for the outer query GROUP BY
+create index iab on t1(a, b);
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+
+explain extended
+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));
+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));
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+
+drop table t1, t2, t3;
+
+#
+# BUG#36133 "Assertion `exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION &&"
+#
+create table t2 (a int, b int, key(a), key(b));
+insert into t2 values (3,3),(3,3),(3,3);
+select 1 from t2 where
+ t2.a > 1
+ or
+ t2.a = 3 and not t2.a not in (select t2.b from t2);
+drop table t2;
+
+#
+# BUG#37896 Assertion on entry of Item_in_subselect::exec on subquery with AND NOT
+#
+create table t1 (a1 int key);
+create table t2 (b1 int);
+insert into t1 values (5);
+
+# Query with group by, executed via materialization
+explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+# Query with group by, executed via IN=>EXISTS
+set @@optimizer_switch='default,materialization=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+
+# Executed with materialization
+set @@optimizer_switch='default,semijoin=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+select min(a1) from t1 where 7 in (select b1 from t2);
+# Executed with semi-join. Notice, this time we get a different result (NULL).
+# This is the only correct result of all four queries. This difference is
+# filed as BUG#40037.
+set @@optimizer_switch='default,materialization=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+select min(a1) from t1 where 7 in (select b1 from t2);
+drop table t1,t2;
+
+#
+# BUG#36752 "subquery materialization produces wrong results when comparing different types"
+#
+create table t1 (a char(2), b varchar(10));
+insert into t1 values ('a', 'aaa');
+insert into t1 values ('aa', 'aaaa');
+
+set @@optimizer_switch='default,semijoin=off';
+explain select a,b from t1 where b in (select a from t1);
+select a,b from t1 where b in (select a from t1);
+prepare st1 from "select a,b from t1 where b in (select a from t1)";
+execute st1;
+execute st1;
+drop table t1;
+
+#
+# Bug #44303 Assertion failures in Field_new_decimal::store_decimal
+# when executing materialized InsideOut semijoin
+#
+CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
+INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
+INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
+INSERT INTO t1 (f1, f2) VALUES (10, 1.668);
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1, 1.789);
+INSERT INTO t2 VALUES (13, 1.454);
+
+SET @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+
+DROP TABLE t1, t2;
+
+#
+# BUG#46548 IN-subqueries return 0 rows with materialization=on
+#
+CREATE TABLE t1 (
+ pk int,
+ a varchar(1),
+ b varchar(4),
+ c varchar(4),
+ d varchar(4),
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
+
+SET @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#50019: Wrong result for IN-subquery with materialization
+--echo #
+create table t1(i int);
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+create table t2(i int);
+insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+create table t3(i int);
+insert into t3 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
+set @save_optimizer_switch=@@optimizer_switch;
+set session optimizer_switch='materialization=off';
+select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+
+#
+# Test that the contents of the temp table of a materialized subquery is
+# cleaned up between PS re-executions.
+#
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+select a, a in (select a from t1) from t0;
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+update t1 set a=123;
+execute s;
+drop table t0, t1;
+
+
+--echo #
+--echo # LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
+--echo # partial_match_table_scan=on
+--echo #
+
+create table t1 (c1 int);
+create table t2 (c2 int);
+insert into t1 values (1);
+insert into t2 values (2);
+
+set @@optimizer_switch='semijoin=off';
+
+EXPLAIN
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+EXPLAIN
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
+
+drop table t1, t2;
+
+--echo #
+--echo # BUG#52344 - Subquery materialization:
+--echo # Assertion if subquery in on-clause of outer join
+--echo #
+
+set @@optimizer_switch='semijoin=off';
+
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (10);
+
+CREATE TABLE t2 (j INTEGER);
+INSERT INTO t2 VALUES (5);
+
+CREATE TABLE t3 (k INTEGER);
+
+EXPLAIN
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
+
+EXPLAIN
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
+--echo # partial_match_table_scan=on
+--echo #
+
+CREATE TABLE t1 (c1 int);
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (c2 int);
+INSERT INTO t2 VALUES (10);
+
+PREPARE st1 FROM "
+SELECT *
+FROM t2 LEFT JOIN (SELECT * FROM t2) t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
+
+EXECUTE st1;
+EXECUTE st1;
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/subselect_no_mat.test b/mysql-test/t/subselect_no_mat.test
new file mode 100644
index 00000000000..5fbbef5caed
--- /dev/null
+++ b/mysql-test/t/subselect_no_mat.test
@@ -0,0 +1,11 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+select @@optimizer_switch like '%materialization=on%';
+set optimizer_switch='materialization=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+select @@optimizer_switch like '%materialization=on%';
+
diff --git a/mysql-test/t/subselect_no_opts.test b/mysql-test/t/subselect_no_opts.test
new file mode 100644
index 00000000000..a26e8dd4c0d
--- /dev/null
+++ b/mysql-test/t/subselect_no_opts.test
@@ -0,0 +1,9 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+set optimizer_switch='materialization=off,semijoin=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+
diff --git a/mysql-test/t/subselect_no_semijoin.test b/mysql-test/t/subselect_no_semijoin.test
new file mode 100644
index 00000000000..e9f2e0654ce
--- /dev/null
+++ b/mysql-test/t/subselect_no_semijoin.test
@@ -0,0 +1,8 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+set optimizer_switch='semijoin=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
diff --git a/mysql-test/t/subselect_notembedded.test b/mysql-test/t/subselect_notembedded.test
index 2f1cc261f56..dcda71c767f 100644
--- a/mysql-test/t/subselect_notembedded.test
+++ b/mysql-test/t/subselect_notembedded.test
@@ -8,6 +8,9 @@
purge master logs before (select adddate(current_timestamp(), interval -4 day));
purge master logs before adddate(current_timestamp(), interval -4 day);
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
#
# Bug31048: Many nested subqueries may cause server crash.
#
@@ -28,6 +31,7 @@ let $end_pre= )group by b limit 1 ;
while ($should_work_nesting)
{
--echo $should_work_nesting
+ eval select $should_work_nesting as 'STEP-1';
eval $start $end;
eval explain $start $end;
let $start= $start
@@ -40,6 +44,7 @@ while ($should_work_nesting)
while ($nesting)
{
--echo $nesting
+ eval select $nesting as 'STEP-2';
--error 0,1436
eval $start $end;
--error 0,1436
diff --git a/mysql-test/t/subselect_nulls.test b/mysql-test/t/subselect_nulls.test
new file mode 100644
index 00000000000..6de7820872c
--- /dev/null
+++ b/mysql-test/t/subselect_nulls.test
@@ -0,0 +1,94 @@
+# Initialize tables for the test
+
+--disable_warnings
+drop table if exists x1;
+drop table if exists x2;
+--enable_warnings
+
+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
+ (10, 10, 10),
+ (20, 20, 20),
+ (21, 20, null),
+ (30, null, 30),
+ (40, 40, 40);
+insert into x2 values
+ (10, 10, 10),
+ (20, 20, 20),
+ (21, 20, null),
+ (30, null, 30);
+
+# Test various IN and EXISTS queries with NULL values and UNKNOWN
+# Q1 T=(10, 20) U=(21,30) F=(40)
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2);
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2) is true;
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2) is false;
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2) is unknown;
+
+# Q2 T=(10, 20) U=(30) F=(21, 40)
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2);
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2) is true;
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2) is false;
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2) is unknown;
+
+# Q3 T=(10, 20) U=() F=(21, 30, 40)
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2);
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2) is true;
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2) is false;
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2) is unknown;
+
+# Q4 T=(10, 20) F=(21, 30, 40)
+select *
+from x1
+where exists (select *
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2);
+
+drop table x1;
+drop table x2;
diff --git a/mysql-test/t/subselect_partial_match.test b/mysql-test/t/subselect_partial_match.test
new file mode 100644
index 00000000000..c5167f827ab
--- /dev/null
+++ b/mysql-test/t/subselect_partial_match.test
@@ -0,0 +1,72 @@
+#
+# Tests for
+# MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs
+#
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+--echo #
+--echo # LP BUG#608744
+--echo #
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off";
+create table t1 (a1 char(1), a2 char(1));
+insert into t1 values (NULL, 'b');
+create table t2 (b1 char(1), b2 char(2));
+insert into t2 values ('a','b'), ('c', 'd');
+select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2);
+drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
+
+--echo #
+--echo # LP BUG#601156
+--echo #
+
+CREATE TABLE t1 (a1 int DEFAULT NULL, a2 int DEFAULT NULL);
+INSERT INTO t1 VALUES (NULL,2);
+INSERT INTO t1 VALUES (4,NULL);
+CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL);
+INSERT INTO t2 VALUES (6,NULL);
+INSERT INTO t2 VALUES (NULL,0);
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
+
+DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # LP BUG#613009 Crash in Ordered_key::get_field_idx
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off';
+
+create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL);
+insert into t1 values (NULL, 'a21'), (NULL, 'a22');
+explain select * from t1 where (a1, a2) not in (select a1, a2 from t1);
+select * from t1 where (a1, a2) not in (select a1, a2 from t1);
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # LP BUG#680058 void Ordered_key::add_key(rownum_t):
+--echo # Assertion `key_buff_elements && cur_key_idx < key_buff_elements' failed
+--echo #
+
+create table t1 (f1 char(1), f2 char(1));
+insert into t1 values ('t', '0'), ('0', 't');
+create table t2 (f3 char(1), f4 char(1));
+insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y');
+
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
+select * from t1 where (f1, f2) not in (select * from t2);
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
new file mode 100644
index 00000000000..18ec4d00677
--- /dev/null
+++ b/mysql-test/t/subselect_sj.test
@@ -0,0 +1,986 @@
+#
+# Nested Loops semi-join subquery evaluation tests
+#
+--disable_warnings
+drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
+--enable_warnings
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+#
+# 1. Subqueries that are converted into semi-joins
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+
+create table t11(a int, b int);
+
+create table t10 (pk int, a int, primary key(pk));
+insert into t10 select a,a from t0;
+create table t12 like t10;
+insert into t12 select * from t10;
+
+
+--echo Flattened because of dependency, t10=func(t1)
+explain select * from t1 where a in (select pk from t10);
+select * from t1 where a in (select pk from t10);
+
+--echo A confluent case of dependency
+explain select * from t1 where a in (select a from t10 where pk=12);
+select * from t1 where a in (select a from t10 where pk=12);
+
+explain select * from t1 where a in (select a from t10 where pk=9);
+select * from t1 where a in (select a from t10 where pk=9);
+
+--echo An empty table inside
+explain select * from t1 where a in (select a from t11);
+select * from t1 where a in (select a from t11);
+
+explain select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+
+--echo flattening a nested subquery
+explain select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+
+--echo flattening subquery w/ several tables
+explain extended select * from t1 where a in (select t10.pk from t10, t12 where t12.pk=t10.a);
+
+--echo subqueries within outer joins go into ON expr.
+# TODO: psergey: check if case conversions like those are ok (it broke on windows)
+--replace_result a A b B
+explain extended
+select * from t1 left join (t2 A, t2 B) on ( A.a= t1.a and B.a in (select pk from t10));
+
+# TODO: psergey: check if case conversions like those are ok (it broke on windows)
+--echo t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
+--replace_result a A b B
+explain extended
+select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10));
+
+--echo we shouldn't flatten if we're going to get a join of > MAX_TABLES.
+explain select * from
+ t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
+ t1 s10, t1 s11, t1 s12, t1 s13, t1 s14,t1 s15,t1 s16,t1 s17,t1 s18,t1 s19,
+ t1 s20, t1 s21, t1 s22, t1 s23, t1 s24,t1 s25,t1 s26,t1 s27,t1 s28,t1 s29,
+ t1 s30, t1 s31, t1 s32, t1 s33, t1 s34,t1 s35,t1 s36,t1 s37,t1 s38,t1 s39,
+ t1 s40, t1 s41, t1 s42, t1 s43, t1 s44,t1 s45,t1 s46,t1 s47,t1 s48,t1 s49
+where
+ s00.a in (
+ select m00.a from
+ t1 m00, t1 m01, t1 m02, t1 m03, t1 m04,t1 m05,t1 m06,t1 m07,t1 m08,t1 m09,
+ t1 m10, t1 m11, t1 m12, t1 m13, t1 m14,t1 m15,t1 m16,t1 m17,t1 m18,t1 m19
+ );
+
+select * from
+ t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+where t1.a < 5;
+
+#
+# Prepared statements
+#
+prepare s1 from
+ ' select * from
+ t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+ where t1.a < 5';
+execute s1;
+execute s1;
+
+# Try I2O orders
+insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B;
+explain extended select * from t1 where a in (select pk from t10 where pk<3);
+
+drop table t0, t1, t2;
+drop table t10, t11, t12;
+
+--echo
+--echo Bug#37899: Wrongly checked optimization prerequisite caused failed
+--echo assertion.
+--echo
+CREATE TABLE t1 (
+ `pk` int(11),
+ `varchar_nokey` varchar(5)
+);
+
+INSERT INTO t1 VALUES
+(1,'qk'),(2,'j'),(3,'aew');
+
+SELECT *
+FROM t1
+WHERE varchar_nokey IN (
+ SELECT
+ varchar_nokey
+ FROM
+ t1
+) XOR pk = 30;
+drop table t1;
+
+--echo #
+--echo # BUG#41842: Semi-join materialization strategy crashes when the upper query has HAVING
+--echo #
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ int_nokey int(11) NOT NULL,
+ time_key time NOT NULL,
+ datetime_key datetime NOT NULL,
+ datetime_nokey datetime NOT NULL,
+ varchar_key varchar(1) NOT NULL,
+ varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY time_key (time_key),
+ KEY datetime_key (datetime_key),
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t1 VALUES
+(1,0, '00:16:10','2008-09-03 14:25:40','2008-09-03 14:25:40','h','h'),
+(2,7, '00:00:00','2001-01-13 00:00:00','2001-01-13 00:00:00','',''),
+(3,0, '00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(4,2, '16:29:24','2000-10-16 01:39:08','2000-10-16 01:39:08','w','w'),
+(5,1, '09:23:32','0000-00-00 00:00:00','0000-00-00 00:00:00','p','p'),
+(6,3, '00:00:00','2007-12-02 00:00:00','2007-12-02 00:00:00','o','o'),
+(7,3, '00:00:00','2008-09-11 00:00:00','2008-09-11 00:00:00','',''),
+(8,0, '13:59:04','0000-00-00 00:00:00','0000-00-00 00:00:00','s','s'),
+(9,7, '09:01:06','0000-00-00 00:00:00','0000-00-00 00:00:00','d','d'),
+(10,5,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','n','n'),
+(11,0,'21:06:46','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(12,2,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','',''),
+(13,6,'14:45:34','2003-07-28 02:34:08','2003-07-28 02:34:08','w','w'),
+(14,1,'15:04:12','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(15,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(16,0,'15:55:23','2004-03-17 00:32:27','2004-03-17 00:32:27','p','p'),
+(17,1,'16:30:00','2004-12-27 19:20:00','2004-12-27 19:20:00','d','d'),
+(18,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','h','h'),
+(19,0,'14:13:26','2008-11-09 05:53:48','2008-11-09 05:53:48','o','o'),
+(20,0,'00:00:00','2009-10-11 06:58:04','2009-10-11 06:58:04','k','k');
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ int_nokey int(11) NOT NULL,
+ time_key time NOT NULL,
+ datetime_key datetime NOT NULL,
+ datetime_nokey datetime NOT NULL,
+ varchar_key varchar(1) NOT NULL,
+ varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY time_key (time_key),
+ KEY datetime_key (datetime_key),
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(10,0,'19:39:13','0000-00-00 00:00:00','0000-00-00 00:00:00','g','g'),
+(11,8,'03:43:53','0000-00-00 00:00:00','0000-00-00 00:00:00','b','b');
+SELECT OUTR.datetime_nokey AS X FROM t1 AS OUTR
+WHERE
+ OUTR.varchar_nokey IN (SELECT
+ INNR . varchar_nokey AS Y
+ FROM t2 AS INNR
+ WHERE
+ INNR . datetime_key >= INNR . time_key OR
+ INNR . pk = INNR . int_nokey
+ )
+ AND OUTR . varchar_nokey <= 'w'
+HAVING X > '2012-12-12';
+drop table t1, t2;
+
+--echo #
+--echo # Bug#45191: Incorrectly initialized semi-join led to a wrong result.
+--echo #
+CREATE TABLE STAFF (EMPNUM CHAR(3) NOT NULL,
+ EMPNAME CHAR(20), GRADE DECIMAL(4), CITY CHAR(15));
+
+CREATE TABLE PROJ (PNUM CHAR(3) NOT NULL,
+ PNAME CHAR(20), PTYPE CHAR(6),
+ BUDGET DECIMAL(9),
+ CITY CHAR(15));
+
+CREATE TABLE WORKS (EMPNUM CHAR(3) NOT NULL,
+ PNUM CHAR(3) NOT NULL, HOURS DECIMAL(5));
+INSERT INTO STAFF VALUES ('E1','Alice',12,'Deale');
+INSERT INTO STAFF VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO STAFF VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO STAFF VALUES ('E4','Don',12,'Deale');
+INSERT INTO STAFF VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO PROJ VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO PROJ VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO PROJ VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO PROJ VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO PROJ VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO PROJ VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO WORKS VALUES ('E1','P1',40);
+INSERT INTO WORKS VALUES ('E1','P2',20);
+INSERT INTO WORKS VALUES ('E1','P3',80);
+INSERT INTO WORKS VALUES ('E1','P4',20);
+INSERT INTO WORKS VALUES ('E1','P5',12);
+INSERT INTO WORKS VALUES ('E1','P6',12);
+INSERT INTO WORKS VALUES ('E2','P1',40);
+INSERT INTO WORKS VALUES ('E2','P2',80);
+INSERT INTO WORKS VALUES ('E3','P2',20);
+INSERT INTO WORKS VALUES ('E4','P2',20);
+INSERT INTO WORKS VALUES ('E4','P4',40);
+INSERT INTO WORKS VALUES ('E4','P5',80);
+
+set optimizer_switch=@save_optimizer_switch;
+set optimizer_switch='materialization=off';
+
+explain SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+ (SELECT EMPNUM FROM WORKS
+ WHERE PNUM IN
+ (SELECT PNUM FROM PROJ));
+
+SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+ (SELECT EMPNUM FROM WORKS
+ WHERE PNUM IN
+ (SELECT PNUM FROM PROJ));
+
+set optimizer_switch=@save_optimizer_switch;
+
+drop table STAFF,WORKS,PROJ;
+
+--echo # End of bug#45191
+
+--echo #
+--echo # Bug#46550 Azalea returning duplicate results for some IN subqueries
+--echo # w/ semijoin=on
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t0, t1, t2;
+--enable_warnings
+
+CREATE TABLE t0 (
+ int_key int(11) DEFAULT NULL,
+ varchar_key varchar(1) DEFAULT NULL,
+ varchar_nokey varchar(1) DEFAULT NULL,
+ KEY int_key (int_key),
+ KEY varchar_key (varchar_key,int_key)
+);
+
+INSERT INTO t0 VALUES
+(1,'m','m'),
+(40,'h','h'),
+(1,'r','r'),
+(1,'h','h'),
+(9,'x','x'),
+(NULL,'q','q'),
+(NULL,'k','k'),
+(7,'l','l'),
+(182,'k','k'),
+(202,'a','a'),
+(7,'x','x'),
+(6,'j','j'),
+(119,'z','z'),
+(4,'d','d'),
+(5,'h','h'),
+(1,'u','u'),
+(3,'q','q'),
+(7,'a','a'),
+(3,'e','e'),
+(6,'l','l');
+
+CREATE TABLE t1 (
+ int_key int(11) DEFAULT NULL,
+ varchar_key varchar(1) DEFAULT NULL,
+ varchar_nokey varchar(1) DEFAULT NULL,
+ KEY int_key (int_key),
+ KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t1 VALUES (7,NULL,NULL),(4,'x','x');
+
+CREATE TABLE t2 (
+ int_key int(11) DEFAULT NULL,
+ varchar_key varchar(1) DEFAULT NULL,
+ varchar_nokey varchar(1) DEFAULT NULL,
+ KEY int_key (int_key),
+ KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t2 VALUES (123,NULL,NULL);
+
+SELECT int_key
+FROM t0
+WHERE varchar_nokey IN (
+ SELECT t1 .varchar_key from t1
+);
+
+SELECT t0.int_key
+FROM t0
+WHERE t0.varchar_nokey IN (
+ SELECT t1_1 .varchar_key
+ FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+
+SELECT t0.int_key
+FROM t0, t2
+WHERE t0.varchar_nokey IN (
+ SELECT t1_1 .varchar_key
+ FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+
+DROP TABLE t0, t1, t2;
+
+--echo # End of bug#46550
+
+--echo #
+--echo # Bug #46744 Crash in optimize_semijoin_nests on empty view
+--echo # with limit and procedure.
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+CREATE TABLE t1 ( f1 int );
+CREATE TABLE t2 ( f1 int );
+
+insert into t2 values (5), (7);
+
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
+
+create procedure p1()
+select COUNT(*)
+FROM v1 WHERE f1 IN
+(SELECT f1 FROM t2 WHERE f1 = ANY (SELECT f1 FROM v1));
+
+SET SESSION optimizer_switch = 'semijoin=on';
+CALL p1();
+SET SESSION optimizer_switch = 'semijoin=off';
+CALL p1();
+
+drop table t1, t2;
+drop view v1;
+drop procedure p1;
+
+set SESSION optimizer_switch=@save_optimizer_switch;
+
+--echo # End of bug#46744
+
+--echo
+--echo Bug#46797 "Crash in fix_semijoin_strategies_for_picked_join_order
+--echo with semijoin=on"
+--echo
+CREATE TABLE t1 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+);
+
+CREATE TABLE t2 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+ (NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+ ('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+ ('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+ ('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+ ('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+ ('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+ ('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+ ('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+
+CREATE TABLE t3 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+ (NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+ ('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+ WHERE (varchar_key,varchar_key)
+ IN (SELECT t1.varchar_key, t2 .varchar_key
+ FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+ )
+ );
+
+DROP TABLE t1, t2, t3;
+
+
+--echo #
+--echo # Bug#46556 Returning incorrect, empty results for some IN subqueries
+--echo # w/semijoin=on
+--echo #
+
+CREATE TABLE t0 (
+ pk INTEGER,
+ vkey VARCHAR(1),
+ vnokey VARCHAR(1),
+ PRIMARY KEY (pk),
+ KEY vkey(vkey)
+);
+
+INSERT INTO t0
+VALUES (1,'g','g'), (2,'v','v'), (3,'t','t'), (4,'u','u'), (5,'n','n');
+
+EXPLAIN EXTENDED SELECT vkey FROM t0 WHERE pk IN
+ (SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+
+SELECT vkey FROM t0 WHERE pk IN
+ (SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+
+DROP TABLE t0;
+
+--echo # End of bug#46556
+
+--echo
+--echo Bug #48073 Subquery on char columns from view crashes Mysql
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ city VARCHAR(50) NOT NULL,
+ country_id SMALLINT UNSIGNED NOT NULL
+);
+
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+
+CREATE TABLE t2 (
+ country_id SMALLINT UNSIGNED NOT NULL,
+ country VARCHAR(50) NOT NULL
+);
+
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'American Samoa') ;
+
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+ SELECT country
+ FROM t2
+ WHERE LEFT(country, 1) = "A"
+);
+
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+ SELECT country
+ FROM v1
+);
+
+drop table t1, t2;
+drop view v1;
+
+--echo # End of bug#48073
+
+--echo
+--echo Bug#48834: Procedure with view + subquery + semijoin=on
+--echo crashes on second call.
+--echo
+
+SET SESSION optimizer_switch ='semijoin=on';
+
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+
+CREATE VIEW v1 AS
+ SELECT t1field as v1field
+ FROM t1 A
+ WHERE A.t1field IN (SELECT t1field FROM t2 );
+
+CREATE VIEW v2 AS
+ SELECT t2field as v2field
+ FROM t2 A
+ WHERE A.t2field IN (SELECT t2field FROM t2 );
+
+DELIMITER |;
+CREATE PROCEDURE p1 ()
+ BEGIN
+ SELECT v1field
+ FROM v1
+ WHERE v1field IN ( SELECT v2field as vf_inner FROM v2 );
+ END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+
+CALL p1;
+CALL p1;
+
+DROP TABLE t1,t2;
+DROP VIEW v1,v2;
+DROP PROCEDURE p1;
+
+set SESSION optimizer_switch=@save_optimizer_switch;
+
+--echo # End of BUG#48834
+
+--echo
+--echo Bug#49097 subquery with view generates wrong result with
+--echo non-prepared statement
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ city VARCHAR(50) NOT NULL,
+ country_id SMALLINT UNSIGNED NOT NULL
+);
+
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+
+CREATE TABLE t2 (
+ country_id SMALLINT UNSIGNED NOT NULL,
+ country VARCHAR(50) NOT NULL
+);
+
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'XAmerican Samoa') ;
+
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM t2
+ WHERE LEFT(country,1) = "A"
+);
+
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM v1
+);
+
+PREPARE stmt FROM
+"
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM v1
+);
+";
+
+execute stmt;
+
+deallocate prepare stmt;
+drop table t1, t2;
+drop view v1;
+
+--echo # End of Bug#49097
+
+--echo #
+--echo # BUG#38075: Wrong result: rows matching a subquery with outer join not returned
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS ot1, it1, it2;
+--enable_warnings
+
+CREATE TABLE it2 (
+ int_key int(11) NOT NULL,
+ datetime_key datetime NOT NULL,
+ KEY int_key (int_key),
+ KEY datetime_key (datetime_key)
+);
+INSERT INTO it2 VALUES
+ (5,'2002-04-10 14:25:30'), (0,'0000-00-00 00:00:00'),
+ (0,'2006-09-14 04:01:02'), (4,'0000-00-00 00:00:00'),
+ (8,'0000-00-00 00:00:00'), (5,'0000-00-00 00:00:00'),
+ (9,'0000-00-00 00:00:00'), (8,'2007-04-01 11:04:17'),
+ (1,'0000-00-00 00:00:00'), (7,'2009-01-12 00:00:00'),
+ (0,'2009-06-05 00:00:00'), (3,'2006-02-14 18:06:35'),
+ (5,'2006-02-21 07:08:16'), (0,'0000-00-00 00:00:00'),
+ (7,'0000-00-00 00:00:00'), (0,'0000-00-00 00:00:00'),
+ (0,'2007-02-13 00:00:00'), (1,'0000-00-00 00:00:00'),
+ (0,'0000-00-00 00:00:00'), (1,'2003-08-11 00:00:00');
+CREATE TABLE ot1 (
+ int_nokey int(11) NOT NULL,
+ int_key int(11) NOT NULL,
+ KEY int_key (int_key)
+);
+INSERT INTO ot1 VALUES
+ (5,0), (3,0), (0,2), (3,0), (1,3), (0,0), (1,7), (7,0), (1,7), (0,7),
+ (0,9), (8,2), (4,4), (9,3), (0,9), (2,5), (0,5), (8,0), (5,8), (1,5);
+CREATE TABLE it1 (
+ int_nokey int(11) NOT NULL,
+ int_key int(11) NOT NULL,
+ KEY int_key (int_key)
+);
+INSERT INTO it1 VALUES
+ (9,5), (0,4);
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+EXPLAIN
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+DROP TABLE ot1, it1, it2;
+
+--echo # End of BUG#38075
+
+--echo #
+--echo # BUG#31480: Incorrect result for nested subquery when executed via semi join
+--echo #
+create table t1 (a int not null, b int not null);
+create table t2 (c int not null, d int not null);
+create table t3 (e int not null);
+
+insert into t1 values (1,10);
+insert into t1 values (2,10);
+insert into t1 values (1,20);
+insert into t1 values (2,20);
+insert into t1 values (3,20);
+insert into t1 values (2,30);
+insert into t1 values (4,40);
+
+insert into t2 values (2,10);
+insert into t2 values (2,20);
+insert into t2 values (4,10);
+insert into t2 values (5,10);
+insert into t2 values (3,20);
+insert into t2 values (2,40);
+
+insert into t3 values (10);
+insert into t3 values (30);
+insert into t3 values (10);
+insert into t3 values (20);
+
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+show warnings;
+
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # Bug#48213 Materialized subselect crashes if using GEOMETRY type
+--echo #
+
+CREATE TABLE t1 (
+ pk int,
+ a varchar(1),
+ b varchar(4),
+ c tinyblob,
+ d blob,
+ e mediumblob,
+ f longblob,
+ g tinytext,
+ h text,
+ i mediumtext,
+ j longtext,
+ k geometry,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff', 'ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))'));
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))'));
+
+# Test that materialization is skipped for semijoins where materialized
+# table would contain GEOMETRY or different kinds of BLOB/TEXT columns
+let $query=
+SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+let $query=
+SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+DROP TABLE t1, t2;
+--echo # End of Bug#48213
+
+--echo #
+--echo # Bug#49198 Wrong result for second call of procedure
+--echo # with view in subselect.
+--echo #
+
+CREATE TABLE t1 (t1field integer, primary key (t1field));
+CREATE TABLE t2 (t2field integer, primary key (t2field));
+CREATE TABLE t3 (t3field integer, primary key (t3field));
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+
+INSERT INTO t1 VALUES(1),(2);
+INSERT INTO t2 VALUES(1),(2);
+INSERT INTO t3 VALUES(1),(2);
+
+PREPARE stmt FROM
+"
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2);
+";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+PREPARE stmt FROM
+"
+EXPLAIN
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2)
+ AND t1field IN (SELECT * FROM v3)
+";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+DROP TABLE t1, t2, t3;
+DROP VIEW v2, v3;
+
+--echo # End of Bug#49198
+
+--echo #
+--echo # Bug#45174: Incorrectly applied equality propagation caused wrong
+--echo # result on a query with a materialized semi-join.
+--echo #
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `varchar_key` varchar(1) NOT NULL,
+ `varchar_nokey` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `varchar_key` (`varchar_key`)
+);
+
+INSERT INTO `t1` VALUES (11,'m','m'),(12,'j','j'),(13,'z','z'),(14,'a','a'),(15,'',''),(16,'e','e'),(17,'t','t'),(19,'b','b'),(20,'w','w'),(21,'m','m'),(23,'',''),(24,'w','w'),(26,'e','e'),(27,'e','e'),(28,'p','p');
+
+CREATE TABLE `t2` (
+ `varchar_nokey` varchar(1) NOT NULL
+);
+
+INSERT INTO `t2` VALUES ('v'),('u'),('n'),('l'),('h'),('u'),('n'),('j'),('k'),('e'),('i'),('u'),('n'),('b'),('x'),(''),('q'),('u');
+
+EXPLAIN EXTENDED SELECT varchar_nokey
+FROM t2
+WHERE ( `varchar_nokey` , `varchar_nokey` ) IN (
+SELECT `varchar_key` , `varchar_nokey`
+FROM t1
+WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
+
+SELECT varchar_nokey
+FROM t2
+WHERE ( `varchar_nokey` , `varchar_nokey` ) IN (
+SELECT `varchar_key` , `varchar_nokey`
+FROM t1
+WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
+
+DROP TABLE t1, t2;
+
+--echo # End of the test for bug#45174.
+--echo #
+--echo # BUG#43768: Prepared query with nested subqueries core dumps on second execution
+--echo #
+create table t1 (
+ id int(11) unsigned not null primary key auto_increment,
+ partner_id varchar(35) not null,
+ t1_status_id int(10) unsigned
+);
+
+insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"),
+ ("3", "partner3", "10"), ("4", "partner4", "10");
+
+create table t2 (
+ id int(11) unsigned not null default '0',
+ t1_line_id int(11) unsigned not null default '0',
+ article_id varchar(20),
+ sequence int(11) not null default '0',
+ primary key (id,t1_line_id)
+);
+
+insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
+ ("2", "2", "sup", "2"), ("2", "3", "sup", "3"),
+ ("2", "4", "imp", "4"), ("3", "1", "sup", "0"),
+ ("4", "1", "sup", "0");
+create table t3 (
+ id int(11) not null default '0',
+ preceeding_id int(11) not null default '0',
+ primary key (id,preceeding_id)
+);
+
+create table t4 (
+ user_id varchar(50) not null,
+ article_id varchar(20) not null,
+ primary key (user_id,article_id)
+);
+
+insert into t4 values("nicke", "imp");
+prepare stmt from
+'select t1.partner_id
+from t1
+where
+ t1.id in (
+ select pl_inner.id
+ from t2 as pl_inner
+ where pl_inner.article_id in (
+ select t4.article_id from t4
+ where t4.user_id = \'nicke\'
+ )
+ )';
+
+execute stmt;
+execute stmt;
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # Bug#48623 Multiple subqueries are optimized incorrectly
+--echo #
+
+CREATE TABLE t1(val VARCHAR(10));
+CREATE TABLE t2(val VARCHAR(10));
+CREATE TABLE t3(val VARCHAR(10));
+
+INSERT INTO t1 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t2 VALUES('aaa'), ('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t3 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+
+EXPLAIN
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+ WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+ AND t1.val IN (SELECT t3.val FROM t3
+ WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+ WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+ AND t1.val IN (SELECT t3.val FROM t3
+ WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+--echo # End of Bug#48623
+
+--echo #
+--echo # LPBUG#602574: RQG: sql_select.cc:5385: bool greedy_search(JOIN*, table_map, uint,
+--echo # uint): Assertion `join->best_read <
+--echo #
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+);
+
+CREATE TABLE t2 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+ (NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+ ('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+ ('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+ ('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+ ('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+ ('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+ ('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+ ('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+
+CREATE TABLE t3 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+ (NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+ ('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+ WHERE (varchar_key,varchar_key)
+ IN (SELECT t1.varchar_key, t2 .varchar_key
+ FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+ )
+ );
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2, t3;
+
+# The following command must be the last one the file
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
new file mode 100644
index 00000000000..e73e7cfade2
--- /dev/null
+++ b/mysql-test/t/subselect_sj2.test
@@ -0,0 +1,904 @@
+#
+# DuplicateElimination strategy test
+#
+--source include/have_innodb.inc
+--disable_warnings
+drop table if exists t0, t1, t2, t3;
+drop view if exists v1;
+--enable_warnings
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+# First test simple cases: I20 order, no join buffering.
+
+create table t1 (
+ a int,
+ b int
+);
+insert into t1 values (1,1),(1,1),(2,2);
+
+create table t2 (
+ a int,
+ b int,
+ key(b)
+);
+insert into t2 select a, a/2 from t0;
+
+select * from t1;
+select * from t2;
+explain select * from t2 where b in (select a from t1);
+select * from t2 where b in (select a from t1);
+
+# Try an InnoDB table with very long rowid
+create table t3 (
+ a int,
+ b int,
+ key(b),
+ 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;
+
+explain select * from t3 where b in (select a from t1);
+select * from t3 where b in (select a from t1);
+
+# Test overflow to MyISAM:
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+
+drop table t3;
+create table t3 (
+ a int,
+ b int,
+ key(b),
+ pk1 char(200), pk2 char(200),
+ primary key(pk1, pk2)
+) engine=innodb;
+insert into t3 select
+ A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
+from t0 A, t0 B where B.a <5;
+
+explain select * from t3 where b in (select a from t0);
+# Because of BUG#40154, run the next select w/o index condition pushdown:
+set @save_ecp= @@engine_condition_pushdown;
+set engine_condition_pushdown=0;
+select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);
+set engine_condition_pushdown=@save_ecp;
+
+set join_buffer_size= @save_join_buffer_size;
+set max_heap_table_size= @save_max_heap_table_size;
+
+# O2I join orders, with shortcutting:
+explain select * from t1 where a in (select b from t2);
+select * from t1;
+select * from t1 where a in (select b from t2);
+
+drop table t1, t2, t3;
+# (no need for anything in range/index_merge/DS-MRR)
+
+#
+# Test join buffering
+#
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+
+create table t1 (a int, filler1 binary(200), filler2 binary(200));
+insert into t1 select a, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+10, 'filler123456', 'filler123456' from t0;
+
+create table t2 as select * from t1;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+
+insert into t1 values (2, 'duplicate ok', 'duplicate ok');
+insert into t1 values (18, 'duplicate ok', 'duplicate ok');
+
+insert into t2 values (3, 'duplicate ok', 'duplicate ok');
+insert into t2 values (19, 'duplicate ok', 'duplicate ok');
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+
+# Now let the buffer overfill:
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+
+drop table t1, t2;
+
+# Check ref access to tables inside the OJ nest inside the SJ nest
+create table t1 (a int, b int, key(a));
+create table t2 (a int, b int, key(a));
+create table t3 (a int, b int, key(a));
+
+insert into t1 select a,a from t0;
+insert into t2 select a,a from t0;
+insert into t3 select a,a from t0;
+
+--echo t2 and t3 must be use 'ref', not 'ALL':
+explain select *
+from t0 where a in
+ (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
+
+drop table t0, t1,t2,t3;
+
+#
+# Bug #27348: Assertion abort for a query with two subqueries to be flattened
+# Bug #35674: Range optimizer ignores conditions on inner tables in semi-join IN subqueries
+#
+CREATE TABLE t1 (
+ ID int(11) NOT NULL auto_increment,
+ Name char(35) NOT NULL default '',
+ Country char(3) NOT NULL default '',
+ Population int(11) NOT NULL default '0',
+ PRIMARY KEY (ID),
+ INDEX (Population),
+ INDEX (Country)
+);
+CREATE TABLE t2 (
+ Code char(3) NOT NULL default '',
+ Name char(52) NOT NULL default '',
+ SurfaceArea float(10,2) NOT NULL default '0.00',
+ Population int(11) NOT NULL default '0',
+ Capital int(11) default NULL,
+ PRIMARY KEY (Code),
+ UNIQUE INDEX (Name),
+ INDEX (Population)
+);
+CREATE TABLE t3 (
+ Country char(3) NOT NULL default '',
+ Language char(30) NOT NULL default '',
+ Percentage float(3,1) NOT NULL default '0.0',
+ PRIMARY KEY (Country, Language),
+ INDEX (Percentage)
+);
+
+--disable_query_log
+INSERT INTO t1 VALUES
+(1,'Kabul','AFG',1780000),(2,'Qandahar','AFG',237500),
+(3,'Herat','AFG',186800),(4,'Mazar-e-Sharif','AFG',127800),
+(5,'Amsterdam','NLD',731200),(6,'Rotterdam','NLD',593321),
+(7,'Haag','NLD',440900),(8,'Utrecht','NLD',234323),
+(9,'Eindhoven','NLD',201843),(10,'Tilburg','NLD',193238),
+(11,'Groningen','NLD',172701),(12,'Breda','NLD',160398),
+(13,'Apeldoorn','NLD',153491),(14,'Nijmegen','NLD',152463),
+(15,'Enschede','NLD',149544),(16,'Haarlem','NLD',148772),
+(17,'Almere','NLD',142465),(18,'Arnhem','NLD',138020),
+(19,'Zaanstad','NLD',135621),(20,'´s-Hertogenbosch','NLD',129170),
+(21,'Amersfoort','NLD',126270),(22,'Maastricht','NLD',122087),
+(23,'Dordrecht','NLD',119811),(24,'Leiden','NLD',117196),
+(25,'Haarlemmermeer','NLD',110722),(26,'Zoetermeer','NLD',110214),
+(27,'Emmen','NLD',105853),(28,'Zwolle','NLD',105819),
+(29,'Ede','NLD',101574),(30,'Delft','NLD',95268);
+
+INSERT INTO t2 VALUES
+('AFG','Afghanistan',652090.00,22720000,1),
+('NLD','Netherlands',41526.00,15864000,5),
+('ANT','Netherlands Antilles',800.00,217000,33),
+('ALB','Albania',28748.00,3401200,34),
+('DZA','Algeria',2381741.00,31471000,35),
+('ASM','American Samoa',199.00,68000,54),
+('AND','Andorra',468.00,78000,55),
+('AGO','Angola',1246700.00,12878000,56),
+('AIA','Anguilla',96.00,8000,62),
+('ATG','Antigua and Barbuda',442.00,68000,63),
+('ARE','United Arab Emirates',83600.00,2441000,65),
+('ARG','Argentina',2780400.00,37032000,69),
+('ARM','Armenia',29800.00,3520000,126),
+('ABW','Aruba',193.00,103000,129),
+('AUS','Australia',7741220.00,18886000,135),
+('AZE','Azerbaijan',86600.00,7734000,144);
+
+INSERT INTO t3 VALUES
+('AFG','Pashto',52.4),('NLD','Dutch',95.6),
+('ANT','Papiamento',86.2),('ALB','Albaniana',97.9),
+('DZA','Arabic',86.0),('ASM','Samoan',90.6),
+('AND','Spanish',44.6),('AGO','Ovimbundu',37.2),
+('AIA','English',0.0),('ATG','Creole English',95.7),
+('ARE','Arabic',42.0),('ARG','Spanish',96.8),
+('ARM','Armenian',93.4),('ABW','Papiamento',76.7),
+('AUS','English',81.2),('AZE','Azerbaijani',89.0),
+('BHS','Creole English',89.7),('BHR','Arabic',67.7),
+('BGD','Bengali',97.7),('BRB','Bajan',95.1),
+('BEL','Dutch',59.2),('BLZ','English',50.8);
+--enable_query_log
+
+EXPLAIN
+SELECT Name FROM t2
+ WHERE t2.Code IN (SELECT Country FROM t1 WHERE Population > 5000000)
+ AND
+ t2.Code IN (SELECT Country FROM t3
+ WHERE Language='English' AND Percentage > 10 AND
+ t2.Population > 100000);
+
+DROP TABLE t1,t2,t3;
+
+# BUG#30993:
+CREATE TABLE t1 (
+ Code char(3) NOT NULL DEFAULT '',
+ Name char(52) NOT NULL DEFAULT '',
+ Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
+ Region char(26) NOT NULL DEFAULT '',
+ SurfaceArea float(10,2) NOT NULL DEFAULT '0.00',
+ IndepYear smallint(6) DEFAULT NULL,
+ Population int(11) NOT NULL DEFAULT '0',
+ LifeExpectancy float(3,1) DEFAULT NULL,
+ GNP float(10,2) DEFAULT NULL,
+ GNPOld float(10,2) DEFAULT NULL,
+ LocalName char(45) NOT NULL DEFAULT '',
+ GovernmentForm char(45) NOT NULL DEFAULT '',
+ HeadOfState char(60) DEFAULT NULL,
+ Capital int(11) DEFAULT NULL,
+ Code2 char(2) NOT NULL DEFAULT '',
+ PRIMARY KEY (Code)
+);
+
+CREATE TABLE t2 (
+ ID int(11) NOT NULL AUTO_INCREMENT,
+ Name char(35) NOT NULL DEFAULT '',
+ CountryCode char(3) NOT NULL DEFAULT '',
+ District char(20) NOT NULL DEFAULT '',
+ Population int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID),
+ KEY CountryCode (CountryCode)
+);
+
+--echo Fill the table with test data
+--disable_query_log
+insert into t2 (ID, Name, CountryCode, Population) values
+(1,'Kabul','AFG',1780000), (2,'Qandahar','AFG',237500), (3,'Herat','AFG',186800),
+(4,'Mazar-e-Sharif','AFG',127800), (33,'Willemstad','ANT',2345), (34,'Tirana','ALB',270000),
+(55,'Andorra la Vella','AND',21189), (61,'South Hill','AIA',961), (62,'The Valley','AIA',595),
+(63,'Saint John�s','ATG',24000), (64,'Dubai','ARE',669181), (65,'Abu Dhabi','ARE',398695),
+(66,'Sharja','ARE',320095), (67,'al-Ayn','ARE',225970), (68,'Ajman','ARE',114395),
+(126,'Yerevan','ARM',1248700), (127,'Gjumri','ARM',211700), (128,'Vanadzor','ARM',172700),
+(129,'Oranjestad','ABW',29034), (144,'Baku','AZE',1787800), (145,'G�nc�','AZE',299300),
+(146,'Sumqayit','AZE',283000), (147,'Ming��evir','AZE',93900), (148,'Nassau','BHS',172000),
+(149,'al-Manama','BHR',148000), (150,'Dhaka','BGD',3612850), (151,'Chittagong','BGD',1392860),
+(152,'Khulna','BGD',663340), (153,'Rajshahi','BGD',294056), (154,'Narayanganj','BGD',202134),
+(155,'Rangpur','BGD',191398), (156,'Mymensingh','BGD',188713), (157,'Barisal','BGD',170232),
+(158,'Tungi','BGD',168702), (159,'Jessore','BGD',139710), (160,'Comilla','BGD',135313),
+(161,'Nawabganj','BGD',130577), (162,'Dinajpur','BGD',127815), (163,'Bogra','BGD',120170),
+(164,'Sylhet','BGD',117396), (165,'Brahmanbaria','BGD',109032), (166,'Tangail','BGD',106004),
+(167,'Jamalpur','BGD',103556), (168,'Pabna','BGD',103277), (169,'Naogaon','BGD',101266),
+(170,'Sirajganj','BGD',99669), (171,'Narsinghdi','BGD',98342), (172,'Saidpur','BGD',96777),
+(173,'Gazipur','BGD',96717), (174,'Bridgetown','BRB',6070), (175,'Antwerpen','BEL',446525),
+(176,'Gent','BEL',224180), (177,'Charleroi','BEL',200827), (178,'Li�ge','BEL',185639),
+(179,'Bruxelles [Brussel]','BEL',133859), (180,'Brugge','BEL',116246), (181,'Schaerbeek','BEL',105692),
+(182,'Namur','BEL',105419), (183,'Mons','BEL',90935), (184,'Belize City','BLZ',55810),
+(185,'Belmopan','BLZ',7105), (190,'Saint George','BMU',1800), (191,'Hamilton','BMU',1200),
+(192,'Thimphu','BTN',22000), (201,'Sarajevo','BIH',360000), (202,'Banja Luka','BIH',143079),
+(203,'Zenica','BIH',96027), (538,'Bandar Seri Begawan','BRN',21484), (539,'Sofija','BGR',1122302),
+(540,'Plovdiv','BGR',342584), (541,'Varna','BGR',299801), (542,'Burgas','BGR',195255),
+(543,'Ruse','BGR',166467), (544,'Stara Zagora','BGR',147939), (545,'Pleven','BGR',121952),
+(546,'Sliven','BGR',105530), (547,'Dobric','BGR',100399), (548,'�umen','BGR',94686),
+(553,'George Town','CYM',19600), (584,'San Jos�','CRI',339131), (1523,'Wien','AUT',1608144),
+(1524,'Graz','AUT',240967), (1525,'Linz','AUT',188022), (1526,'Salzburg','AUT',144247),
+(1527,'Innsbruck','AUT',111752), (1528,'Klagenfurt','AUT',91141), (1810,'Montr�al','CAN',1016376),
+(1811,'Calgary','CAN',768082), (1812,'Toronto','CAN',688275), (1813,'North York','CAN',622632),
+(1814,'Winnipeg','CAN',618477), (1815,'Edmonton','CAN',616306), (1816,'Mississauga','CAN',608072),
+(1817,'Scarborough','CAN',594501), (1818,'Vancouver','CAN',514008), (1819,'Etobicoke','CAN',348845),
+(1820,'London','CAN',339917), (1821,'Hamilton','CAN',335614), (1822,'Ottawa','CAN',335277),
+(1823,'Laval','CAN',330393), (1824,'Surrey','CAN',304477), (1825,'Brampton','CAN',296711),
+(1826,'Windsor','CAN',207588), (1827,'Saskatoon','CAN',193647), (1828,'Kitchener','CAN',189959),
+(1829,'Markham','CAN',189098), (1830,'Regina','CAN',180400), (1831,'Burnaby','CAN',179209),
+(1832,'Qu�bec','CAN',167264), (1833,'York','CAN',154980), (1834,'Richmond','CAN',148867),
+(1835,'Vaughan','CAN',147889), (1836,'Burlington','CAN',145150), (1837,'Oshawa','CAN',140173),
+(1838,'Oakville','CAN',139192), (1839,'Saint Catharines','CAN',136216), (1840,'Longueuil','CAN',127977),
+(1841,'Richmond Hill','CAN',116428), (1842,'Thunder Bay','CAN',115913), (1843,'Nepean','CAN',115100),
+(1844,'Cape Breton','CAN',114733), (1845,'East York','CAN',114034), (1846,'Halifax','CAN',113910),
+(1847,'Cambridge','CAN',109186), (1848,'Gloucester','CAN',107314), (1849,'Abbotsford','CAN',105403),
+(1850,'Guelph','CAN',103593), (1851,'Saint John�s','CAN',101936), (1852,'Coquitlam','CAN',101820),
+(1853,'Saanich','CAN',101388), (1854,'Gatineau','CAN',100702), (1855,'Delta','CAN',95411),
+(1856,'Sudbury','CAN',92686), (1857,'Kelowna','CAN',89442), (1858,'Barrie','CAN',89269),
+(1890,'Shanghai','CHN',9696300), (1891,'Peking','CHN',7472000), (1892,'Chongqing','CHN',6351600),
+(1893,'Tianjin','CHN',5286800), (1894,'Wuhan','CHN',4344600), (1895,'Harbin','CHN',4289800),
+(1896,'Shenyang','CHN',4265200), (1897,'Kanton [Guangzhou]','CHN',4256300), (1898,'Chengdu','CHN',3361500),
+(1899,'Nanking [Nanjing]','CHN',2870300), (1900,'Changchun','CHN',2812000), (1901,'Xi�an','CHN',2761400),
+(1902,'Dalian','CHN',2697000), (1903,'Qingdao','CHN',2596000), (1904,'Jinan','CHN',2278100),
+(1905,'Hangzhou','CHN',2190500), (1906,'Zhengzhou','CHN',2107200), (1907,'Shijiazhuang','CHN',2041500),
+(1908,'Taiyuan','CHN',1968400), (1909,'Kunming','CHN',1829500), (1910,'Changsha','CHN',1809800),
+(1911,'Nanchang','CHN',1691600), (1912,'Fuzhou','CHN',1593800), (1913,'Lanzhou','CHN',1565800),
+(1914,'Guiyang','CHN',1465200), (1915,'Ningbo','CHN',1371200), (1916,'Hefei','CHN',1369100),
+(1917,'Urumt�i [�r�mqi]','CHN',1310100), (1918,'Anshan','CHN',1200000), (1919,'Fushun','CHN',1200000),
+(1920,'Nanning','CHN',1161800), (1921,'Zibo','CHN',1140000), (1922,'Qiqihar','CHN',1070000),
+(1923,'Jilin','CHN',1040000), (1924,'Tangshan','CHN',1040000), (1925,'Baotou','CHN',980000),
+(1926,'Shenzhen','CHN',950500), (1927,'Hohhot','CHN',916700), (1928,'Handan','CHN',840000),
+(1929,'Wuxi','CHN',830000), (1930,'Xuzhou','CHN',810000), (1931,'Datong','CHN',800000),
+(1932,'Yichun','CHN',800000), (1933,'Benxi','CHN',770000), (1934,'Luoyang','CHN',760000),
+(1935,'Suzhou','CHN',710000), (1936,'Xining','CHN',700200), (1937,'Huainan','CHN',700000),
+(1938,'Jixi','CHN',683885), (1939,'Daqing','CHN',660000), (1940,'Fuxin','CHN',640000),
+(1941,'Amoy [Xiamen]','CHN',627500), (1942,'Liuzhou','CHN',610000), (1943,'Shantou','CHN',580000),
+(1944,'Jinzhou','CHN',570000), (1945,'Mudanjiang','CHN',570000), (1946,'Yinchuan','CHN',544500),
+(1947,'Changzhou','CHN',530000), (1948,'Zhangjiakou','CHN',530000), (1949,'Dandong','CHN',520000),
+(1950,'Hegang','CHN',520000), (1951,'Kaifeng','CHN',510000), (1952,'Jiamusi','CHN',493409),
+(1953,'Liaoyang','CHN',492559), (1954,'Hengyang','CHN',487148), (1955,'Baoding','CHN',483155),
+(1956,'Hunjiang','CHN',482043), (1957,'Xinxiang','CHN',473762), (1958,'Huangshi','CHN',457601),
+(1959,'Haikou','CHN',454300), (1960,'Yantai','CHN',452127), (1961,'Bengbu','CHN',449245),
+(1962,'Xiangtan','CHN',441968), (1963,'Weifang','CHN',428522), (1964,'Wuhu','CHN',425740),
+(1965,'Pingxiang','CHN',425579), (1966,'Yingkou','CHN',421589), (1967,'Anyang','CHN',420332),
+(1968,'Panzhihua','CHN',415466), (1969,'Pingdingshan','CHN',410775), (1970,'Xiangfan','CHN',410407),
+(1971,'Zhuzhou','CHN',409924), (1972,'Jiaozuo','CHN',409100), (1973,'Wenzhou','CHN',401871),
+(1974,'Zhangjiang','CHN',400997), (1975,'Zigong','CHN',393184), (1976,'Shuangyashan','CHN',386081),
+(1977,'Zaozhuang','CHN',380846), (1978,'Yakeshi','CHN',377869), (1979,'Yichang','CHN',371601),
+(1980,'Zhenjiang','CHN',368316), (1981,'Huaibei','CHN',366549), (1982,'Qinhuangdao','CHN',364972),
+(1983,'Guilin','CHN',364130), (1984,'Liupanshui','CHN',363954), (1985,'Panjin','CHN',362773),
+(1986,'Yangquan','CHN',362268), (1987,'Jinxi','CHN',357052), (1988,'Liaoyuan','CHN',354141),
+(1989,'Lianyungang','CHN',354139), (1990,'Xianyang','CHN',352125), (1991,'Tai�an','CHN',350696),
+(1992,'Chifeng','CHN',350077), (1993,'Shaoguan','CHN',350043), (1994,'Nantong','CHN',343341),
+(1995,'Leshan','CHN',341128), (1996,'Baoji','CHN',337765), (1997,'Linyi','CHN',324720),
+(1998,'Tonghua','CHN',324600), (1999,'Siping','CHN',317223), (2000,'Changzhi','CHN',317144),
+(2001,'Tengzhou','CHN',315083), (2002,'Chaozhou','CHN',313469), (2003,'Yangzhou','CHN',312892),
+(2004,'Dongwan','CHN',308669), (2005,'Ma�anshan','CHN',305421), (2006,'Foshan','CHN',303160),
+(2007,'Yueyang','CHN',302800), (2008,'Xingtai','CHN',302789), (2009,'Changde','CHN',301276),
+(2010,'Shihezi','CHN',299676), (2011,'Yancheng','CHN',296831), (2012,'Jiujiang','CHN',291187),
+(2013,'Dongying','CHN',281728), (2014,'Shashi','CHN',281352), (2015,'Xintai','CHN',281248),
+(2016,'Jingdezhen','CHN',281183), (2017,'Tongchuan','CHN',280657), (2018,'Zhongshan','CHN',278829),
+(2019,'Shiyan','CHN',273786), (2020,'Tieli','CHN',265683), (2021,'Jining','CHN',265248),
+(2022,'Wuhai','CHN',264081), (2023,'Mianyang','CHN',262947), (2024,'Luzhou','CHN',262892),
+(2025,'Zunyi','CHN',261862), (2026,'Shizuishan','CHN',257862), (2027,'Neijiang','CHN',256012),
+(2028,'Tongliao','CHN',255129), (2029,'Tieling','CHN',254842), (2030,'Wafangdian','CHN',251733),
+(2031,'Anqing','CHN',250718), (2032,'Shaoyang','CHN',247227), (2033,'Laiwu','CHN',246833),
+(2034,'Chengde','CHN',246799), (2035,'Tianshui','CHN',244974), (2036,'Nanyang','CHN',243303),
+(2037,'Cangzhou','CHN',242708), (2038,'Yibin','CHN',241019), (2039,'Huaiyin','CHN',239675),
+(2040,'Dunhua','CHN',235100), (2041,'Yanji','CHN',230892), (2042,'Jiangmen','CHN',230587),
+(2043,'Tongling','CHN',228017), (2044,'Suihua','CHN',227881), (2045,'Gongziling','CHN',226569),
+(2046,'Xiantao','CHN',222884), (2047,'Chaoyang','CHN',222394), (2048,'Ganzhou','CHN',220129),
+(2049,'Huzhou','CHN',218071), (2050,'Baicheng','CHN',217987), (2051,'Shangzi','CHN',215373),
+(2052,'Yangjiang','CHN',215196), (2053,'Qitaihe','CHN',214957), (2054,'Gejiu','CHN',214294),
+(2055,'Jiangyin','CHN',213659), (2056,'Hebi','CHN',212976), (2057,'Jiaxing','CHN',211526),
+(2058,'Wuzhou','CHN',210452), (2059,'Meihekou','CHN',209038), (2060,'Xuchang','CHN',208815),
+(2061,'Liaocheng','CHN',207844), (2062,'Haicheng','CHN',205560), (2063,'Qianjiang','CHN',205504),
+(2064,'Baiyin','CHN',204970), (2065,'Bei�an','CHN',204899), (2066,'Yixing','CHN',200824),
+(2067,'Laizhou','CHN',198664), (2068,'Qaramay','CHN',197602), (2069,'Acheng','CHN',197595),
+(2070,'Dezhou','CHN',195485), (2071,'Nanping','CHN',195064), (2072,'Zhaoqing','CHN',194784),
+(2073,'Beipiao','CHN',194301), (2074,'Fengcheng','CHN',193784), (2075,'Fuyu','CHN',192981),
+(2076,'Xinyang','CHN',192509), (2077,'Dongtai','CHN',192247), (2078,'Yuci','CHN',191356),
+(2079,'Honghu','CHN',190772), (2080,'Ezhou','CHN',190123), (2081,'Heze','CHN',189293),
+(2082,'Daxian','CHN',188101), (2083,'Linfen','CHN',187309), (2084,'Tianmen','CHN',186332),
+(2085,'Yiyang','CHN',185818), (2086,'Quanzhou','CHN',185154), (2087,'Rizhao','CHN',185048),
+(2088,'Deyang','CHN',182488), (2089,'Guangyuan','CHN',182241), (2090,'Changshu','CHN',181805),
+(2091,'Zhangzhou','CHN',181424), (2092,'Hailar','CHN',180650), (2093,'Nanchong','CHN',180273),
+(2094,'Jiutai','CHN',180130), (2095,'Zhaodong','CHN',179976), (2096,'Shaoxing','CHN',179818),
+(2097,'Fuyang','CHN',179572), (2098,'Maoming','CHN',178683), (2099,'Qujing','CHN',178669),
+(2100,'Ghulja','CHN',177193), (2101,'Jiaohe','CHN',176367), (2102,'Puyang','CHN',175988),
+(2103,'Huadian','CHN',175873), (2104,'Jiangyou','CHN',175753), (2105,'Qashqar','CHN',174570),
+(2106,'Anshun','CHN',174142), (2107,'Fuling','CHN',173878), (2108,'Xinyu','CHN',173524),
+(2109,'Hanzhong','CHN',169930), (2110,'Danyang','CHN',169603), (2111,'Chenzhou','CHN',169400),
+(2112,'Xiaogan','CHN',166280), (2113,'Shangqiu','CHN',164880), (2114,'Zhuhai','CHN',164747),
+(2115,'Qingyuan','CHN',164641), (2116,'Aqsu','CHN',164092), (2117,'Jining','CHN',163552),
+(2118,'Xiaoshan','CHN',162930), (2119,'Zaoyang','CHN',162198), (2120,'Xinghua','CHN',161910),
+(2121,'Hami','CHN',161315), (2122,'Huizhou','CHN',161023), (2123,'Jinmen','CHN',160794),
+(2124,'Sanming','CHN',160691), (2125,'Ulanhot','CHN',159538), (2126,'Korla','CHN',159344),
+(2127,'Wanxian','CHN',156823), (2128,'Rui�an','CHN',156468), (2129,'Zhoushan','CHN',156317),
+(2130,'Liangcheng','CHN',156307), (2131,'Jiaozhou','CHN',153364), (2132,'Taizhou','CHN',152442),
+(2133,'Suzhou','CHN',151862), (2134,'Yichun','CHN',151585), (2135,'Taonan','CHN',150168),
+(2136,'Pingdu','CHN',150123), (2137,'Ji�an','CHN',148583), (2138,'Longkou','CHN',148362),
+(2139,'Langfang','CHN',148105), (2140,'Zhoukou','CHN',146288), (2141,'Suining','CHN',146086),
+(2142,'Yulin','CHN',144467), (2143,'Jinhua','CHN',144280), (2144,'Liu�an','CHN',144248),
+(2145,'Shuangcheng','CHN',142659), (2146,'Suizhou','CHN',142302), (2147,'Ankang','CHN',142170),
+(2148,'Weinan','CHN',140169), (2149,'Longjing','CHN',139417), (2150,'Da�an','CHN',138963),
+(2151,'Lengshuijiang','CHN',137994), (2152,'Laiyang','CHN',137080), (2153,'Xianning','CHN',136811),
+(2154,'Dali','CHN',136554), (2155,'Anda','CHN',136446), (2156,'Jincheng','CHN',136396),
+(2157,'Longyan','CHN',134481), (2158,'Xichang','CHN',134419), (2159,'Wendeng','CHN',133910),
+(2160,'Hailun','CHN',133565), (2161,'Binzhou','CHN',133555), (2162,'Linhe','CHN',133183),
+(2163,'Wuwei','CHN',133101), (2164,'Duyun','CHN',132971), (2165,'Mishan','CHN',132744),
+(2166,'Shangrao','CHN',132455), (2167,'Changji','CHN',132260), (2168,'Meixian','CHN',132156),
+(2169,'Yushu','CHN',131861), (2170,'Tiefa','CHN',131807), (2171,'Huai�an','CHN',131149),
+(2172,'Leiyang','CHN',130115), (2173,'Zalantun','CHN',130031), (2174,'Weihai','CHN',128888),
+(2175,'Loudi','CHN',128418), (2176,'Qingzhou','CHN',128258), (2177,'Qidong','CHN',126872),
+(2178,'Huaihua','CHN',126785), (2179,'Luohe','CHN',126438), (2180,'Chuzhou','CHN',125341),
+(2181,'Kaiyuan','CHN',124219), (2182,'Linqing','CHN',123958), (2183,'Chaohu','CHN',123676),
+(2184,'Laohekou','CHN',123366), (2185,'Dujiangyan','CHN',123357), (2186,'Zhumadian','CHN',123232),
+(2187,'Linchuan','CHN',121949), (2188,'Jiaonan','CHN',121397), (2189,'Sanmenxia','CHN',120523),
+(2190,'Heyuan','CHN',120101), (2191,'Manzhouli','CHN',120023), (2192,'Lhasa','CHN',120000),
+(2193,'Lianyuan','CHN',118858), (2194,'Kuytun','CHN',118553), (2195,'Puqi','CHN',117264),
+(2196,'Hongjiang','CHN',116188), (2197,'Qinzhou','CHN',114586), (2198,'Renqiu','CHN',114256),
+(2199,'Yuyao','CHN',114065), (2200,'Guigang','CHN',114025), (2201,'Kaili','CHN',113958),
+(2202,'Yan�an','CHN',113277), (2203,'Beihai','CHN',112673), (2204,'Xuangzhou','CHN',112673),
+(2205,'Quzhou','CHN',112373), (2206,'Yong�an','CHN',111762), (2207,'Zixing','CHN',110048),
+(2208,'Liyang','CHN',109520), (2209,'Yizheng','CHN',109268), (2210,'Yumen','CHN',109234),
+(2211,'Liling','CHN',108504), (2212,'Yuncheng','CHN',108359), (2213,'Shanwei','CHN',107847),
+(2214,'Cixi','CHN',107329), (2215,'Yuanjiang','CHN',107004), (2216,'Bozhou','CHN',106346),
+(2217,'Jinchang','CHN',105287), (2218,'Fu�an','CHN',105265), (2219,'Suqian','CHN',105021),
+(2220,'Shishou','CHN',104571), (2221,'Hengshui','CHN',104269), (2222,'Danjiangkou','CHN',103211),
+(2223,'Fujin','CHN',103104), (2224,'Sanya','CHN',102820), (2225,'Guangshui','CHN',102770),
+(2226,'Huangshan','CHN',102628), (2227,'Xingcheng','CHN',102384), (2228,'Zhucheng','CHN',102134),
+(2229,'Kunshan','CHN',102052), (2230,'Haining','CHN',100478), (2231,'Pingliang','CHN',99265),
+(2232,'Fuqing','CHN',99193), (2233,'Xinzhou','CHN',98667), (2234,'Jieyang','CHN',98531),
+(2235,'Zhangjiagang','CHN',97994), (2236,'Tong Xian','CHN',97168), (2237,'Ya�an','CHN',95900),
+(2238,'Jinzhou','CHN',95761), (2239,'Emeishan','CHN',94000), (2240,'Enshi','CHN',93056),
+(2241,'Bose','CHN',93009), (2242,'Yuzhou','CHN',92889), (2243,'Kaiyuan','CHN',91999),
+(2244,'Tumen','CHN',91471), (2245,'Putian','CHN',91030), (2246,'Linhai','CHN',90870),
+(2247,'Xilin Hot','CHN',90646), (2248,'Shaowu','CHN',90286), (2249,'Junan','CHN',90222),
+(2250,'Huaying','CHN',89400), (2251,'Pingyi','CHN',89373), (2252,'Huangyan','CHN',89288),
+(2413,'La Habana','CUB',2256000), (2414,'Santiago de Cuba','CUB',433180), (2415,'Camag�ey','CUB',298726),
+(2416,'Holgu�n','CUB',249492), (2417,'Santa Clara','CUB',207350), (2418,'Guant�namo','CUB',205078),
+(2419,'Pinar del R�o','CUB',142100), (2420,'Bayamo','CUB',141000), (2421,'Cienfuegos','CUB',132770),
+(2422,'Victoria de las Tunas','CUB',132350), (2423,'Matanzas','CUB',123273), (2424,'Manzanillo','CUB',109350),
+(2425,'Sancti-Sp�ritus','CUB',100751), (2426,'Ciego de �vila','CUB',98505), (2430,'Nicosia','CYP',195000),
+(2431,'Limassol','CYP',154400), (3245,'Z�rich','CHE',336800), (3246,'Geneve','CHE',173500),
+(3247,'Basel','CHE',166700), (3248,'Bern','CHE',122700), (3249,'Lausanne','CHE',114500),
+(3339,'Praha','CZE',1181126), (3340,'Brno','CZE',381862), (3341,'Ostrava','CZE',320041),
+(3342,'Plzen','CZE',166759), (3343,'Olomouc','CZE',102702), (3344,'Liberec','CZE',99155),
+(3345,'Cesk� Budejovice','CZE',98186), (3346,'Hradec Kr�lov�','CZE',98080), (3347,'�st� nad Labem','CZE',95491),
+(3348,'Pardubice','CZE',91309), (3520,'Minsk','BLR',1674000), (3521,'Gomel','BLR',475000),
+(3522,'Mogiljov','BLR',356000), (3523,'Vitebsk','BLR',340000), (3524,'Grodno','BLR',302000),
+(3525,'Brest','BLR',286000), (3526,'Bobruisk','BLR',221000), (3527,'Baranovit�i','BLR',167000),
+(3528,'Borisov','BLR',151000), (3529,'Pinsk','BLR',130000), (3530,'Or�a','BLR',124000),
+(3531,'Mozyr','BLR',110000), (3532,'Novopolotsk','BLR',106000), (3533,'Lida','BLR',101000),
+(3534,'Soligorsk','BLR',101000), (3535,'Molodet�no','BLR',97000);
+
+insert into t1 (Code, Name, Continent) values
+('AFG','Afghanistan','Asia'), ('ANT','Netherlands Antilles','North America'),
+('ALB','Albania','Europe'), ('AND','Andorra','Europe'),
+('AIA','Anguilla','North America'), ('ATG','Antigua and Barbuda','North America'),
+('ARE','United Arab Emirates','Asia'), ('ARM','Armenia','Asia'),
+('ABW','Aruba','North America'), ('AZE','Azerbaijan','Asia'),
+('BHS','Bahamas','North America'), ('BHR','Bahrain','Asia'),
+('BGD','Bangladesh','Asia'), ('BRB','Barbados','North America'),
+('BEL','Belgium','Europe'), ('BLZ','Belize','North America'),
+('BMU','Bermuda','North America'), ('BTN','Bhutan','Asia'),
+('BIH','Bosnia and Herzegovina','Europe'), ('BRN','Brunei','Asia'),
+('BGR','Bulgaria','Europe'), ('CYM','Cayman Islands','North America'),
+('CRI','Costa Rica','North America'), ('AUT','Austria','Europe'),
+('CAN','Canada','North America'), ('CHN','China','Asia'),
+('CUB','Cuba','North America'), ('CYP','Cyprus','Asia'),
+('CHE','Switzerland','Europe'), ('CZE','Czech Republic','Europe'),
+('BLR','Belarus','Europe');
+update t2 set population=6000000 where Name in ('Wien', 'Vancouver', 'Praha');
+--enable_query_log
+
+--echo This must not use LooseScan:
+EXPLAIN SELECT Name FROM t1
+ WHERE t1.Code IN (
+ SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+
+SELECT Name FROM t1
+ WHERE t1.Code IN (
+ SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+
+drop table t1, t2;
+
+#
+# Bug#33062: subquery in stored routine cause crash
+#
+
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(c INT);
+
+DELIMITER //;
+
+CREATE PROCEDURE p1(v1 int)
+BEGIN
+ SELECT 1 FROM t1 WHERE a = v1 AND a IN (SELECT c FROM t2);
+END
+//
+
+CREATE PROCEDURE p2(v1 int)
+BEGIN
+ SELECT 1 FROM t1 WHERE a IN (SELECT c FROM t2);
+END
+//
+
+CREATE PROCEDURE p3(v1 int)
+BEGIN
+ SELECT 1
+ FROM
+ t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+ t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+ t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+ t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+ t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+ t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+ t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+ t1 t57,t1 t58,t1 t59,t1 t60
+ WHERE t01.a IN (SELECT c FROM t2);
+END
+//
+
+CREATE PROCEDURE p4(v1 int)
+BEGIN
+ SELECT 1
+ FROM
+ t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+ t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+ t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+ t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+ t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+ t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+ t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+ t1 t57,t1 t58,t1 t59,t1 t60
+ WHERE t01.a = v1 AND t01.a IN (SELECT c FROM t2);
+END
+//
+
+DELIMITER ;//
+
+CALL p1(1);
+CALL p2(1);
+CALL p3(1);
+CALL p4(1);
+
+DROP TABLE t1, t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+
+
+#
+# BUG#35160 "Subquery optimization: table pullout is not reflected in EXPLAIN EXTENDED"
+#
+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;
+
+create table t2 (a int, b int, primary key(a));
+insert into t2 select * from t1;
+
+# Table t2 should be pulled out because t2.a=t0.a equality
+--echo Table t2, unlike table t1, should be displayed as pulled out
+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);
+
+#
+# BUG#46556 "Returning incorrect, empty results for some IN subqueries
+# w/ semijoin=on"
+#
+
+# The above query did not have a valid plan before the fix of BUG#46556.
+# Add some data that would cause wrong result with the old plan.
+update t1 set a=3, b=11 where a=4;
+update t2 set b=11 where a=3;
+
+if (`select @@join_cache_level=6`)
+{
+ --echo # Not anymore:
+ --echo # The following query gives wrong result due to Bug#49129
+}
+select * from t0 where t0.a in
+ (select t1.a from t1, t2 where t2.a=t0.a and t1.b=t2.b);
+
+drop table t0, t1, t2;
+
+#
+# BUG#35767: Processing of uncorrelated subquery with semi-join cause wrong result and crash
+#
+CREATE TABLE t1 (
+ id int(11) NOT NULL,
+ PRIMARY KEY (id));
+
+CREATE TABLE t2 (
+ id int(11) NOT NULL,
+ fid int(11) NOT NULL,
+ PRIMARY KEY (id));
+
+insert into t1 values(1);
+insert into t2 values(1,7503),(2,1);
+
+--error 1054
+explain select count(*)
+from t1
+where fid IN (select fid from t2 where (id between 7502 and 8420) order by fid );
+
+drop table t1, t2;
+
+#
+# BUG#36137 "virtual longlong Item_in_subselect::val_int(): Assertion `0' failed."
+#
+create table t1 (a int, b int, key (a), key (b));
+insert into t1 values (2,4),(2,4),(2,4);
+select t1.a from t1
+where
+ t1.a in (select 1 from t1 where t1.a in (select 1 from t1) group by t1.a);
+drop table t1;
+
+#
+# BUG#36128: not in subquery causes crash in cleanup..
+#
+create table t1(a int,b int,key(a),key(b));
+insert into t1 values (1,1),(2,2),(3,3);
+select 1 from t1
+where t1.a not in (select 1 from t1
+ where t1.a in (select 1 from t1)
+ group by t1.b);
+drop table t1;
+
+#
+# BUG#33743 "nested subqueries, unique index, wrong result"
+#
+CREATE TABLE t1
+ (EMPNUM CHAR(3) NOT NULL,
+ EMPNAME CHAR(20),
+ GRADE DECIMAL(4),
+ CITY CHAR(15));
+
+CREATE TABLE t2
+ (PNUM CHAR(3) NOT NULL,
+ PNAME CHAR(20),
+ PTYPE CHAR(6),
+ BUDGET DECIMAL(9),
+ CITY CHAR(15));
+
+CREATE TABLE t3
+ (EMPNUM CHAR(3) NOT NULL,
+ PNUM CHAR(3) NOT NULL,
+ HOURS DECIMAL(5));
+
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+
+
+SELECT * FROM t1;
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+DROP INDEX t1_IDX ON t1;
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+DROP TABLE t1, t2, t3;
+
+#
+# BUG#33245 "Crash on VIEW referencing FROM table in an IN clause"
+#
+CREATE TABLE t1 (f1 INT NOT NULL);
+CREATE VIEW v1 (a) AS SELECT f1 IN (SELECT f1 FROM t1) FROM t1;
+SELECT * FROM v1;
+drop view v1;
+drop table t1;
+
+
+#
+# BUG#35550 "Semi-join subquery in ON clause and no WHERE crashes the server"
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+
+create table t3 (pk int, a int, primary key(pk));
+insert into t3 select a,a from t0;
+
+explain
+select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
+
+drop table t0, t1, t2, t3;
+
+#
+# BUG#34799: crash or/and memory overrun with dependant subquery and some joins
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t2 (a char(200), b char(200), c char(200), primary key (a,b,c)) engine=innodb;
+insert into t2 select concat(a, repeat('X',198)),repeat('B',200),repeat('B',200) from t1;
+insert into t2 select concat(a, repeat('Y',198)),repeat('B',200),repeat('B',200) from t1;
+alter table t2 add filler1 int;
+
+insert into t1 select A.a + 10*(B.a + 10*C.a) from t1 A, t1 B, t1 C;
+
+set @save_join_buffer_size=@@join_buffer_size;
+--disable_warnings
+set join_buffer_size=1;
+--enable_warnings
+
+select * from t2 where filler1 in ( select a from t1);
+set join_buffer_size=default;
+
+drop table t1, t2;
+#
+# BUG#33509: Server crashes with number of recursive subqueries=61
+# (the query may or may not fail with an error so we're using it with SP
+#
+create table t1 (a int not null);
+
+--disable_warnings
+drop procedure if exists p1;
+--enable_warnings
+
+delimiter |;
+
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE EXIT HANDLER FOR SQLEXCEPTION select a from t1;
+ prepare s1 from '
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in ( select a from t1)
+ )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
+ execute s1;
+END;
+|
+delimiter ;|
+
+call p1();
+drop procedure p1;
+drop table t1;
+
+#
+# BUG#35468 "Slowdown and wrong result for uncorrelated subquery w/o where"
+#
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int) as select A.a + 10 *(B.a + 10*C.a) as a from t0 A, t0 B, t0 C;
+create table t2 (id int, a int, primary key(id), key(a)) as select a as id, a as a from t1;
+show create table t2;
+set @a=0;
+create table t3 as select * from t2 limit 0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+
+alter table t3 add primary key(id), add key(a);
+--echo The following must use loose index scan over t3, key a:
+explain select count(a) from t2 where a in ( SELECT a FROM t3);
+select count(a) from t2 where a in ( SELECT a FROM t3);
+
+drop table t0,t1,t2,t3;
+
+--echo
+--echo BUG#42740: crash in optimize_semijoin_nests
+--echo
+create table t1 (c6 timestamp,key (c6)) engine=innodb;
+create table t2 (c2 double) engine=innodb;
+explain select 1 from t2 where c2 = any (select log10(null) from t1 where c6 <null) ;
+drop table t1, t2;
+
+--echo #
+--echo # BUG#42742: crash in setup_sj_materialization, Copy_field::set
+--echo #
+create table t3 ( c1 year) engine=innodb;
+insert into t3 values (2135),(2142);
+create table t2 (c1 tinytext,c2 text,c6 timestamp) engine=innodb;
+-- echo # The following must not crash, EXPLAIN should show one SJ strategy, not a mix:
+explain select 1 from t2 where
+ c2 in (select 1 from t3, t2) and
+ c1 in (select convert(c6,char(1)) from t2);
+drop table t2, t3;
+
diff --git a/mysql-test/t/subselect_sj2_jcl6.test b/mysql-test/t/subselect_sj2_jcl6.test
new file mode 100644
index 00000000000..5292a56f266
--- /dev/null
+++ b/mysql-test/t/subselect_sj2_jcl6.test
@@ -0,0 +1,18 @@
+#
+# Run subselect_sj2.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/subselect_sj2.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+
diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test
new file mode 100644
index 00000000000..27c864fc699
--- /dev/null
+++ b/mysql-test/t/subselect_sj_jcl6.test
@@ -0,0 +1,45 @@
+#
+# Run subselect_sj.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/subselect_sj.test
+
+--echo #
+--echo # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
+--echo #
+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;
+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;
+UPDATE t2 SET b=11 WHERE a=3;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='firstmatch=off';
+
+--echo The following should use a join order of t0,t1,t2, with DuplicateElimination:
+explain
+SELECT * FROM t0 WHERE t0.a IN
+ (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+SELECT * FROM t0 WHERE t0.a IN
+ (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+set optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+
+--echo # End
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test
index f595f195dcc..16e9b2361f9 100644
--- a/mysql-test/t/trigger_notembedded.test
+++ b/mysql-test/t/trigger_notembedded.test
@@ -916,7 +916,7 @@ INSERT INTO t1 VALUES (5);
CONNECTION rl_contender;
# Wait until wl_acquirer is waiting for the read lock on t2 to be released.
let $wait_condition=
- SELECT STATE = 'Locked' FROM INFORMATION_SCHEMA.PROCESSLIST
+ SELECT STATE = "Table Lock" FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $wl_acquirer_thread_id;
--source include/wait_condition.inc
# must not "see" the row inserted by the INSERT (as it must run before the
diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test
index b7d31948d23..b7d31948d23 100755..100644
--- a/mysql-test/t/windows.test
+++ b/mysql-test/t/windows.test
diff --git a/mysys/queues.c b/mysys/queues.c
index 9c85e493141..d1f2dab18bc 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -1,25 +1,42 @@
-/* Copyright (C) 2000, 2005 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; 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 */
+/* Copyright (C) 2010 Monty Program Ab
+ All Rights reserved
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
/*
+ This code originates from the Unireg project.
+
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
- An optimisation of _downheap suggested in Exercise 7.51 in "Data
- Structures & Algorithms in C++" by Mark Allen Weiss, Second Edition
- was implemented by Mikael Ronstrom 2005. Also the O(N) algorithm
- of queue_fix was implemented.
+
+ The queue can optionally store the position in queue in the element
+ that is in the queue. This allows one to remove any element from the queue
+ in O(1) time.
+
+ Optimisation of _downheap() and queue_fix() is inspired by code done
+ by Mikael Ronström, based on an optimisation of _downheap from
+ Exercise 7.51 in "Data Structures & Algorithms in C++" by Mark Allen
+ Weiss, Second Edition.
*/
#include "mysys_priv.h"
@@ -39,6 +56,10 @@
max_at_top Set to 1 if you want biggest element on top.
compare Compare function for elements, takes 3 arguments.
first_cmp_arg First argument to compare function
+ offset_to_queue_pos If <> 0, then offset+1 in element to store position
+ in queue (for fast delete of element in queue)
+ auto_extent When the queue is full and there is insert operation
+ extend the queue.
NOTES
Will allocate max_element pointers for queue array
@@ -50,74 +71,33 @@
int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg)
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent)
+
{
DBUG_ENTER("init_queue");
- if ((queue->root= (uchar **) my_malloc((max_elements+1)*sizeof(void*),
+ if ((queue->root= (uchar **) my_malloc((max_elements + 1) * sizeof(void*),
MYF(MY_WME))) == 0)
DBUG_RETURN(1);
- queue->elements=0;
- queue->compare=compare;
- queue->first_cmp_arg=first_cmp_arg;
- queue->max_elements=max_elements;
- queue->offset_to_key=offset_to_key;
+ queue->elements= 0;
+ queue->compare= compare;
+ queue->first_cmp_arg= first_cmp_arg;
+ queue->max_elements= max_elements;
+ queue->offset_to_key= offset_to_key;
+ queue->offset_to_queue_pos= offset_to_queue_pos;
+ queue->auto_extent= auto_extent;
queue_set_max_at_top(queue, max_at_top);
DBUG_RETURN(0);
}
-
-/*
- Init queue, uses init_queue internally for init work but also accepts
- auto_extent as parameter
-
- SYNOPSIS
- init_queue_ex()
- queue Queue to initialise
- max_elements Max elements that will be put in queue
- offset_to_key Offset to key in element stored in queue
- Used when sending pointers to compare function
- max_at_top Set to 1 if you want biggest element on top.
- compare Compare function for elements, takes 3 arguments.
- first_cmp_arg First argument to compare function
- auto_extent When the queue is full and there is insert operation
- extend the queue.
-
- NOTES
- Will allocate max_element pointers for queue array
-
- RETURN
- 0 ok
- 1 Could not allocate memory
-*/
-
-int init_queue_ex(QUEUE *queue, uint max_elements, uint offset_to_key,
- pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg, uint auto_extent)
-{
- int ret;
- DBUG_ENTER("init_queue_ex");
-
- if ((ret= init_queue(queue, max_elements, offset_to_key, max_at_top, compare,
- first_cmp_arg)))
- DBUG_RETURN(ret);
-
- queue->auto_extent= auto_extent;
- DBUG_RETURN(0);
-}
-
/*
Reinitialize queue for other usage
SYNOPSIS
reinit_queue()
queue Queue to initialise
- max_elements Max elements that will be put in queue
- offset_to_key Offset to key in element stored in queue
- Used when sending pointers to compare function
- max_at_top Set to 1 if you want biggest element on top.
- compare Compare function for elements, takes 3 arguments.
- first_cmp_arg First argument to compare function
+ For rest of arguments, see init_queue() above
NOTES
This will delete all elements from the queue. If you don't want this,
@@ -125,21 +105,23 @@ int init_queue_ex(QUEUE *queue, uint max_elements, uint offset_to_key,
RETURN
0 ok
- EE_OUTOFMEMORY Wrong max_elements
+ 1 Wrong max_elements; Queue has old size
*/
int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg)
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent)
{
DBUG_ENTER("reinit_queue");
- queue->elements=0;
- queue->compare=compare;
- queue->first_cmp_arg=first_cmp_arg;
- queue->offset_to_key=offset_to_key;
+ queue->elements= 0;
+ queue->compare= compare;
+ queue->first_cmp_arg= first_cmp_arg;
+ queue->offset_to_key= offset_to_key;
+ queue->offset_to_queue_pos= offset_to_queue_pos;
+ queue->auto_extent= auto_extent;
queue_set_max_at_top(queue, max_at_top);
- resize_queue(queue, max_elements);
- DBUG_RETURN(0);
+ DBUG_RETURN(resize_queue(queue, max_elements));
}
@@ -167,8 +149,8 @@ int resize_queue(QUEUE *queue, uint max_elements)
if (queue->max_elements == max_elements)
DBUG_RETURN(0);
if ((new_root= (uchar **) my_realloc((void *)queue->root,
- (max_elements+1)*sizeof(void*),
- MYF(MY_WME))) == 0)
+ (max_elements + 1)* sizeof(void*),
+ MYF(MY_WME))) == 0)
DBUG_RETURN(1);
set_if_smaller(queue->elements, max_elements);
queue->max_elements= max_elements;
@@ -197,39 +179,58 @@ void delete_queue(QUEUE *queue)
if (queue->root)
{
my_free((uchar*) queue->root,MYF(0));
- queue->root=0;
+ queue->root=0; /* Allow multiple calls */
}
DBUG_VOID_RETURN;
}
- /* Code for insert, search and delete of elements */
+/*
+ Insert element in queue
+
+ SYNOPSIS
+ queue_insert()
+ queue Queue to use
+ element Element to insert
+*/
void queue_insert(register QUEUE *queue, uchar *element)
{
reg2 uint idx, next;
+ uint offset_to_queue_pos= queue->offset_to_queue_pos;
DBUG_ASSERT(queue->elements < queue->max_elements);
- queue->root[0]= element;
+
idx= ++queue->elements;
/* max_at_top swaps the comparison if we want to order by desc */
- while ((queue->compare(queue->first_cmp_arg,
+ while (idx > 1 &&
+ (queue->compare(queue->first_cmp_arg,
element + queue->offset_to_key,
queue->root[(next= idx >> 1)] +
queue->offset_to_key) * queue->max_at_top) < 0)
{
queue->root[idx]= queue->root[next];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx= next;
}
queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element+ offset_to_queue_pos-1))= idx;
}
+
/*
- Does safe insert. If no more space left on the queue resize it.
- Return codes:
- 0 - OK
- 1 - Cannot allocate more memory
- 2 - auto_extend is 0, the operation would
-
+ Like queue_insert, but resize queue if queue is full
+
+ SYNOPSIS
+ queue_insert_safe()
+ queue Queue to use
+ element Element to insert
+
+ RETURN
+ 0 OK
+ 1 Cannot allocate more memory
+ 2 auto_extend is 0; No insertion done
*/
int queue_insert_safe(register QUEUE *queue, uchar *element)
@@ -239,7 +240,7 @@ int queue_insert_safe(register QUEUE *queue, uchar *element)
{
if (!queue->auto_extent)
return 2;
- else if (resize_queue(queue, queue->max_elements + queue->auto_extent))
+ if (resize_queue(queue, queue->max_elements + queue->auto_extent))
return 1;
}
@@ -248,40 +249,51 @@ int queue_insert_safe(register QUEUE *queue, uchar *element)
}
- /* Remove item from queue */
- /* Returns pointer to removed element */
+/*
+ Remove item from queue
+
+ SYNOPSIS
+ queue_remove()
+ queue Queue to use
+ element Index of element to remove.
+ First element in queue is 'queue_first_element(queue)'
+
+ RETURN
+ pointer to removed element
+*/
uchar *queue_remove(register QUEUE *queue, uint idx)
{
uchar *element;
- DBUG_ASSERT(idx < queue->max_elements);
- element= queue->root[++idx]; /* Intern index starts from 1 */
- queue->root[idx]= queue->root[queue->elements--];
- _downheap(queue, idx);
+ DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
+ element= queue->root[idx];
+ _downheap(queue, idx, queue->root[queue->elements--]);
return element;
}
- /* Fix when element on top has been replaced */
-#ifndef queue_replaced
-void queue_replaced(QUEUE *queue)
-{
- _downheap(queue,1);
-}
-#endif
+/*
+ Add element to fixed position and update heap
-#ifndef OLD_VERSION
+ SYNOPSIS
+ _downheap()
+ queue Queue to use
+ idx Index of element to change
+ element Element to store at 'idx'
+
+ NOTE
+ This only works if element is >= all elements <= start_idx
+*/
-void _downheap(register QUEUE *queue, uint idx)
+void _downheap(register QUEUE *queue, uint start_idx, uchar *element)
{
- uchar *element;
- uint elements,half_queue,offset_to_key, next_index;
+ uint elements,half_queue,offset_to_key, next_index, offset_to_queue_pos;
+ register uint idx= start_idx;
my_bool first= TRUE;
- uint start_idx= idx;
offset_to_key=queue->offset_to_key;
- element=queue->root[idx];
- half_queue=(elements=queue->elements) >> 1;
+ offset_to_queue_pos= queue->offset_to_queue_pos;
+ half_queue= (elements= queue->elements) >> 1;
while (idx <= half_queue)
{
@@ -298,393 +310,68 @@ void _downheap(register QUEUE *queue, uint idx)
element+offset_to_key) * queue->max_at_top) >= 0)))
{
queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element + offset_to_queue_pos-1))= idx;
return;
}
- queue->root[idx]=queue->root[next_index];
- idx=next_index;
first= FALSE;
- }
-
- next_index= idx >> 1;
- while (next_index > start_idx)
- {
- if ((queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key) *
- queue->max_at_top) < 0)
- break;
- queue->root[idx]=queue->root[next_index];
+ queue->root[idx]= queue->root[next_index];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx=next_index;
- next_index= idx >> 1;
}
- queue->root[idx]=element;
-}
-#else
/*
- The old _downheap version is kept for comparisons with the benchmark
- suit or new benchmarks anyone wants to run for comparisons.
+ Insert the element into the right position. This is the same code
+ as we have in queue_insert()
*/
- /* Fix heap when index have changed */
-void _downheap(register QUEUE *queue, uint idx)
-{
- uchar *element;
- uint elements,half_queue,next_index,offset_to_key;
-
- offset_to_key=queue->offset_to_key;
- element=queue->root[idx];
- half_queue=(elements=queue->elements) >> 1;
-
- while (idx <= half_queue)
+ while ((next_index= (idx >> 1)) > start_idx &&
+ queue->compare(queue->first_cmp_arg,
+ element+offset_to_key,
+ queue->root[next_index]+offset_to_key)*
+ queue->max_at_top < 0)
{
- next_index=idx+idx;
- if (next_index < elements &&
- (queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- queue->root[next_index+1]+offset_to_key) *
- queue->max_at_top) > 0)
- next_index++;
- if ((queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key) * queue->max_at_top) >= 0)
- break;
- queue->root[idx]=queue->root[next_index];
- idx=next_index;
+ queue->root[idx]= queue->root[next_index];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
+ idx= next_index;
}
- queue->root[idx]=element;
+ queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element + offset_to_queue_pos-1))= idx;
}
-#endif
-
/*
Fix heap when every element was changed.
+
+ SYNOPSIS
+ queue_fix()
+ queue Queue to use
*/
void queue_fix(QUEUE *queue)
{
uint i;
for (i= queue->elements >> 1; i > 0; i--)
- _downheap(queue, i);
+ _downheap(queue, i, queue_element(queue, i));
}
-#ifdef MAIN
- /*
- A test program for the priority queue implementation.
- It can also be used to benchmark changes of the implementation
- Build by doing the following in the directory mysys
- make test_priority_queue
- ./test_priority_queue
-
- Written by Mikael Ronström, 2005
- */
-
-static uint num_array[1025];
-static uint tot_no_parts= 0;
-static uint tot_no_loops= 0;
-static uint expected_part= 0;
-static uint expected_num= 0;
-static bool max_ind= 0;
-static bool fix_used= 0;
-static ulonglong start_time= 0;
-
-static bool is_divisible_by(uint num, uint divisor)
-{
- uint quotient= num / divisor;
- if (quotient * divisor == num)
- return TRUE;
- return FALSE;
-}
-
-void calculate_next()
-{
- uint part= expected_part, num= expected_num;
- uint no_parts= tot_no_parts;
- if (max_ind)
- {
- do
- {
- while (++part <= no_parts)
- {
- if (is_divisible_by(num, part) &&
- (num <= ((1 << 21) + part)))
- {
- expected_part= part;
- expected_num= num;
- return;
- }
- }
- part= 0;
- } while (--num);
- }
- else
- {
- do
- {
- while (--part > 0)
- {
- if (is_divisible_by(num, part))
- {
- expected_part= part;
- expected_num= num;
- return;
- }
- }
- part= no_parts + 1;
- } while (++num);
- }
-}
-void calculate_end_next(uint part)
-{
- uint no_parts= tot_no_parts, num;
- num_array[part]= 0;
- if (max_ind)
- {
- expected_num= 0;
- for (part= no_parts; part > 0 ; part--)
- {
- if (num_array[part])
- {
- num= num_array[part] & 0x3FFFFF;
- if (num >= expected_num)
- {
- expected_num= num;
- expected_part= part;
- }
- }
- }
- if (expected_num == 0)
- expected_part= 0;
- }
- else
- {
- expected_num= 0xFFFFFFFF;
- for (part= 1; part <= no_parts; part++)
- {
- if (num_array[part])
- {
- num= num_array[part] & 0x3FFFFF;
- if (num <= expected_num)
- {
- expected_num= num;
- expected_part= part;
- }
- }
- }
- if (expected_num == 0xFFFFFFFF)
- expected_part= 0;
- }
- return;
-}
-static int test_compare(void *null_arg, uchar *a, uchar *b)
-{
- uint a_num= (*(uint*)a) & 0x3FFFFF;
- uint b_num= (*(uint*)b) & 0x3FFFFF;
- uint a_part, b_part;
- if (a_num > b_num)
- return +1;
- if (a_num < b_num)
- return -1;
- a_part= (*(uint*)a) >> 22;
- b_part= (*(uint*)b) >> 22;
- if (a_part < b_part)
- return +1;
- if (a_part > b_part)
- return -1;
- return 0;
-}
-
-bool check_num(uint num_part)
-{
- uint part= num_part >> 22;
- uint num= num_part & 0x3FFFFF;
- if (part == expected_part)
- if (num == expected_num)
- return FALSE;
- printf("Expect part %u Expect num 0x%x got part %u num 0x%x max_ind %u fix_used %u \n",
- expected_part, expected_num, part, num, max_ind, fix_used);
- return TRUE;
-}
-
-
-void perform_insert(QUEUE *queue)
-{
- uint i= 1, no_parts= tot_no_parts;
- uint backward_start= 0;
-
- expected_part= 1;
- expected_num= 1;
-
- if (max_ind)
- backward_start= 1 << 21;
-
- do
- {
- uint num= (i + backward_start);
- if (max_ind)
- {
- while (!is_divisible_by(num, i))
- num--;
- if (max_ind && (num > expected_num ||
- (num == expected_num && i < expected_part)))
- {
- expected_num= num;
- expected_part= i;
- }
- }
- num_array[i]= num + (i << 22);
- if (fix_used)
- queue_element(queue, i-1)= (uchar*)&num_array[i];
- else
- queue_insert(queue, (uchar*)&num_array[i]);
- } while (++i <= no_parts);
- if (fix_used)
- {
- queue->elements= no_parts;
- queue_fix(queue);
- }
-}
-
-bool perform_ins_del(QUEUE *queue, bool max_ind)
-{
- uint i= 0, no_loops= tot_no_loops, j= tot_no_parts;
- do
- {
- uint num_part= *(uint*)queue_top(queue);
- uint part= num_part >> 22;
- if (check_num(num_part))
- return TRUE;
- if (j++ >= no_loops)
- {
- calculate_end_next(part);
- queue_remove(queue, (uint) 0);
- }
- else
- {
- calculate_next();
- if (max_ind)
- num_array[part]-= part;
- else
- num_array[part]+= part;
- queue_top(queue)= (uchar*)&num_array[part];
- queue_replaced(queue);
- }
- } while (++i < no_loops);
- return FALSE;
-}
-
-bool do_test(uint no_parts, uint l_max_ind, bool l_fix_used)
-{
- QUEUE queue;
- bool result;
- max_ind= l_max_ind;
- fix_used= l_fix_used;
- init_queue(&queue, no_parts, 0, max_ind, test_compare, NULL);
- tot_no_parts= no_parts;
- tot_no_loops= 1024;
- perform_insert(&queue);
- if ((result= perform_ins_del(&queue, max_ind)))
- delete_queue(&queue);
- if (result)
- {
- printf("Error\n");
- return TRUE;
- }
- return FALSE;
-}
-
-static void start_measurement()
-{
- start_time= my_getsystime();
-}
-
-static void stop_measurement()
-{
- ulonglong stop_time= my_getsystime();
- uint time_in_micros;
- stop_time-= start_time;
- stop_time/= 10; /* Convert to microseconds */
- time_in_micros= (uint)stop_time;
- printf("Time expired is %u microseconds \n", time_in_micros);
-}
-
-static void benchmark_test()
-{
- QUEUE queue_real;
- QUEUE *queue= &queue_real;
- uint i, add;
- fix_used= TRUE;
- max_ind= FALSE;
- tot_no_parts= 1024;
- init_queue(queue, tot_no_parts, 0, max_ind, test_compare, NULL);
- /*
- First benchmark whether queue_fix is faster than using queue_insert
- for sizes of 16 partitions.
- */
- for (tot_no_parts= 2, add=2; tot_no_parts < 128;
- tot_no_parts+= add, add++)
- {
- printf("Start benchmark queue_fix, tot_no_parts= %u \n", tot_no_parts);
- start_measurement();
- for (i= 0; i < 128; i++)
- {
- perform_insert(queue);
- queue_remove_all(queue);
- }
- stop_measurement();
+/*
+ Change element at fixed position
- fix_used= FALSE;
- printf("Start benchmark queue_insert\n");
- start_measurement();
- for (i= 0; i < 128; i++)
- {
- perform_insert(queue);
- queue_remove_all(queue);
- }
- stop_measurement();
- }
- /*
- Now benchmark insertion and deletion of 16400 elements.
- Used in consecutive runs this shows whether the optimised _downheap
- is faster than the standard implementation.
- */
- printf("Start benchmarking _downheap \n");
- start_measurement();
- perform_insert(queue);
- for (i= 0; i < 65536; i++)
- {
- uint num, part;
- num= *(uint*)queue_top(queue);
- num+= 16;
- part= num >> 22;
- num_array[part]= num;
- queue_top(queue)= (uchar*)&num_array[part];
- queue_replaced(queue);
- }
- for (i= 0; i < 16; i++)
- queue_remove(queue, (uint) 0);
- queue_remove_all(queue);
- stop_measurement();
-}
+ SYNOPSIS
+ queue_replace()
+ queue Queue to use
+ idx Index of element to change
+ element Element to store at 'idx'
+*/
-int main()
+void queue_replace(QUEUE *queue, uint idx)
{
- int i, add= 1;
- for (i= 1; i < 1024; i+=add, add++)
- {
- printf("Start test for priority queue of size %u\n", i);
- if (do_test(i, 0, 1))
- return -1;
- if (do_test(i, 1, 1))
- return -1;
- if (do_test(i, 0, 0))
- return -1;
- if (do_test(i, 1, 0))
- return -1;
- }
- benchmark_test();
- printf("OK\n");
- return 0;
+ uchar *element= queue->root[idx];
+ DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
+ queue_remove(queue, idx);
+ queue_insert(queue, element);
}
-#endif
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 0d0ae2dabe5..0e489263c69 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -224,6 +224,8 @@ void *_myrealloc(register void *ptr, register size_t size,
struct st_irem *irem;
char *data;
DBUG_ENTER("_myrealloc");
+ DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) ptr,
+ (ulong) size, MyFlags));
if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR))
DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags));
@@ -245,6 +247,8 @@ void *_myrealloc(register void *ptr, register size_t size,
(void) fflush(stderr);
DBUG_RETURN((uchar*) NULL);
}
+ DBUG_PRINT("my", ("old_size: %lu -> new_size: %lu",
+ (ulong) irem->datasize, (ulong) size));
if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
{
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index 386691be4de..98c746af8ca 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -36,11 +36,24 @@
uint thr_client_alarm;
static int alarm_aborted=1; /* No alarm thread */
-my_bool thr_alarm_inited= 0;
+my_bool thr_alarm_inited= 0, my_disable_thr_alarm= 0;
volatile my_bool alarm_thread_running= 0;
time_t next_alarm_expire_time= ~ (time_t) 0;
static sig_handler process_alarm_part2(int sig);
+#ifdef DBUG_OFF
+#define reset_index_in_queue(alarm_data)
+#else
+#define reset_index_in_queue(alarm_data) alarm_data->index_in_queue= 0;
+#endif /* DBUG_OFF */
+
+#ifndef USE_ONE_SIGNAL_HAND
+#define one_signal_hand_sigmask(A,B,C) pthread_sigmask((A), (B), (C))
+#else
+#define one_signal_hand_sigmask(A,B,C)
+#endif
+
+
#if !defined(__WIN__)
static pthread_mutex_t LOCK_alarm;
@@ -72,8 +85,8 @@ void init_thr_alarm(uint max_alarms)
DBUG_ENTER("init_thr_alarm");
alarm_aborted=0;
next_alarm_expire_time= ~ (time_t) 0;
- init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
- compare_ulong,NullS);
+ init_queue(&alarm_queue, max_alarms+1, offsetof(ALARM,expire_time), 0,
+ compare_ulong, NullS, offsetof(ALARM, index_in_queue)+1, 0);
sigfillset(&full_signal_set); /* Neaded to block signals */
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_alarm,NULL);
@@ -151,7 +164,7 @@ void resize_thr_alarm(uint max_alarms)
my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
{
- time_t now;
+ time_t now, next;
#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
#endif
@@ -160,80 +173,77 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
DBUG_ENTER("thr_alarm");
DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
- now= my_time(0);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
-#endif
- pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
- if (alarm_aborted > 0)
+ if (my_disable_thr_alarm)
+ {
+ (*alrm)= &alarm_data->alarmed;
+ alarm_data->alarmed= 1; /* Abort if interrupted */
+ DBUG_RETURN(0);
+ }
+
+ if (unlikely(alarm_aborted))
{ /* No signal thread */
DBUG_PRINT("info", ("alarm aborted"));
- *alrm= 0; /* No alarm */
- pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- if (alarm_aborted < 0)
+ if (alarm_aborted > 0)
+ goto abort_no_unlock;
sec= 1; /* Abort mode */
+ }
+ now= my_time(0);
+ if (!alarm_data)
+ {
+ if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
+ goto abort_no_unlock;
+ alarm_data->malloced= 1;
+ }
+ else
+ alarm_data->malloced= 0;
+ next= now + sec;
+ alarm_data->expire_time= next;
+ alarm_data->alarmed= 0;
+ alarm_data->thread= current_my_thread_var->pthread_self;
+ alarm_data->thread_id= current_my_thread_var->id;
+
+ one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
+ pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
if (alarm_queue.elements >= max_used_alarms)
{
if (alarm_queue.elements == alarm_queue.max_elements)
{
DBUG_PRINT("info", ("alarm queue full"));
fprintf(stderr,"Warning: thr_alarm queue is full\n");
- *alrm= 0; /* No alarm */
- pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
+ goto abort;
}
max_used_alarms=alarm_queue.elements+1;
}
- reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec;
- if (!alarm_data)
- {
- if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
- {
- DBUG_PRINT("info", ("failed my_malloc()"));
- *alrm= 0; /* No alarm */
- pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- alarm_data->malloced=1;
- }
- else
- alarm_data->malloced=0;
- alarm_data->expire_time=now+sec;
- alarm_data->alarmed=0;
- alarm_data->thread= current_my_thread_var->pthread_self;
- alarm_data->thread_id= current_my_thread_var->id;
+ reschedule= (ulong) next_alarm_expire_time > (ulong) next;
queue_insert(&alarm_queue,(uchar*) alarm_data);
+ assert(alarm_data->index_in_queue > 0);
/* Reschedule alarm if the current one has more than sec left */
- if (reschedule)
+ if (unlikely(reschedule))
{
DBUG_PRINT("info", ("reschedule"));
if (pthread_equal(pthread_self(),alarm_thread))
{
alarm(sec); /* purecov: inspected */
- next_alarm_expire_time= now + sec;
+ next_alarm_expire_time= next;
}
else
reschedule_alarms(); /* Reschedule alarms */
}
pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
+ one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
(*alrm)= &alarm_data->alarmed;
DBUG_RETURN(0);
+
+abort:
+ if (alarm_data->malloced)
+ my_free(alarm_data, MYF(0));
+ pthread_mutex_unlock(&LOCK_alarm);
+ one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
+abort_no_unlock:
+ *alrm= 0; /* No alarm */
+ DBUG_RETURN(1);
}
@@ -247,41 +257,20 @@ void thr_end_alarm(thr_alarm_t *alarmed)
#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
#endif
- uint i, found=0;
DBUG_ENTER("thr_end_alarm");
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
-#endif
- pthread_mutex_lock(&LOCK_alarm);
-
+ if (my_disable_thr_alarm)
+ DBUG_VOID_RETURN;
+ one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
- for (i=0 ; i < alarm_queue.elements ; i++)
- {
- if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
- {
- queue_remove(&alarm_queue,i),MYF(0);
- if (alarm_data->malloced)
- my_free((uchar*) alarm_data,MYF(0));
- found++;
-#ifdef DBUG_OFF
- break;
-#endif
- }
- }
- DBUG_ASSERT(!*alarmed || found == 1);
- if (!found)
- {
- if (*alarmed)
- fprintf(stderr,"Warning: Didn't find alarm 0x%lx in queue of %d alarms\n",
- (long) *alarmed, alarm_queue.elements);
- DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n",
- (long) *alarmed));
- }
+ pthread_mutex_lock(&LOCK_alarm);
+ DBUG_ASSERT(alarm_data->index_in_queue != 0);
+ DBUG_ASSERT(queue_element(&alarm_queue, alarm_data->index_in_queue) ==
+ alarm_data);
+ queue_remove(&alarm_queue, alarm_data->index_in_queue);
pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
+ one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
+ reset_index_in_queue(alarm_data);
DBUG_VOID_RETURN;
}
@@ -344,12 +333,13 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
#if defined(MAIN) && !defined(__bsdi__)
printf("process_alarm\n"); fflush(stdout);
#endif
- if (alarm_queue.elements)
+ if (likely(alarm_queue.elements))
{
- if (alarm_aborted)
+ if (unlikely(alarm_aborted))
{
uint i;
- for (i=0 ; i < alarm_queue.elements ;)
+ for (i= queue_first_element(&alarm_queue) ;
+ i <= queue_last_element(&alarm_queue) ;)
{
alarm_data=(ALARM*) queue_element(&alarm_queue,i);
alarm_data->alarmed=1; /* Info to thread */
@@ -360,6 +350,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
printf("Warning: pthread_kill couldn't find thread!!!\n");
#endif
queue_remove(&alarm_queue,i); /* No thread. Remove alarm */
+ reset_index_in_queue(alarm_data);
}
else
i++; /* Signal next thread */
@@ -371,8 +362,8 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
}
else
{
- ulong now=(ulong) my_time(0);
- ulong next=now+10-(now%10);
+ time_t now= my_time(0);
+ time_t next= now+10-(now%10);
while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
{
alarm_data->alarmed=1; /* Info to thread */
@@ -382,15 +373,16 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
{
#ifdef MAIN
printf("Warning: pthread_kill couldn't find thread!!!\n");
-#endif
- queue_remove(&alarm_queue,0); /* No thread. Remove alarm */
+#endif /* MAIN */
+ queue_remove_top(&alarm_queue); /* No thread. Remove alarm */
+ reset_index_in_queue(alarm_data);
if (!alarm_queue.elements)
break;
}
else
{
alarm_data->expire_time=next;
- queue_replaced(&alarm_queue);
+ queue_replace_top(&alarm_queue);
}
}
#ifndef USE_ALARM_THREAD
@@ -483,21 +475,27 @@ void end_thr_alarm(my_bool free_structures)
void thr_alarm_kill(my_thread_id thread_id)
{
uint i;
+ DBUG_ENTER("thr_alarm_kill");
+
if (alarm_aborted)
return;
pthread_mutex_lock(&LOCK_alarm);
- for (i=0 ; i < alarm_queue.elements ; i++)
+ for (i= queue_first_element(&alarm_queue) ;
+ i <= queue_last_element(&alarm_queue);
+ i++)
{
- if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id)
+ ALARM *element= (ALARM*) queue_element(&alarm_queue,i);
+ if (element->thread_id == thread_id)
{
- ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
- tmp->expire_time=0;
- queue_insert(&alarm_queue,(uchar*) tmp);
+ DBUG_PRINT("info", ("found thread; Killing it"));
+ element->expire_time= 0;
+ queue_replace(&alarm_queue, i);
reschedule_alarms();
break;
}
}
pthread_mutex_unlock(&LOCK_alarm);
+ DBUG_VOID_RETURN;
}
@@ -508,7 +506,7 @@ void thr_alarm_info(ALARM_INFO *info)
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
{
- ulong now=(ulong) my_time(0);
+ time_t now= my_time(0);
long time_diff;
ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
time_diff= (long) (alarm_data->expire_time - now);
@@ -556,7 +554,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
{
if (alarm_queue.elements)
{
- ulong sleep_time,now= my_time(0);
+ time_t sleep_time,now= my_time(0);
if (alarm_aborted)
sleep_time=now+1;
else
@@ -792,19 +790,6 @@ static void *test_thread(void *arg)
return 0;
}
-#ifdef USE_ONE_SIGNAL_HAND
-static sig_handler print_signal_warning(int sig)
-{
- printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name());
- fflush(stdout);
-#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
- my_sigset(sig,print_signal_warning); /* int. thread system calls */
-#endif
- if (sig == SIGALRM)
- alarm(2); /* reschedule alarm */
-}
-#endif /* USE_ONE_SIGNAL_HAND */
-
static void *signal_hand(void *arg __attribute__((unused)))
{
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 68a3caf6da7..32b258c0536 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -228,14 +228,16 @@ static void check_locks(THR_LOCK *lock, const char *where,
if (found_errors < MAX_FOUND_ERRORS)
{
- uint count=0;
+ uint count=0, count2= 0;
THR_LOCK_DATA *data;
for (data=lock->read.data ; data ; data=data->next)
{
+ count2++;
if (data->type == TL_READ_NO_INSERT)
count++;
/* Protect against infinite loop. */
- DBUG_ASSERT(count <= lock->read_no_write_count);
+ DBUG_ASSERT(count <= lock->read_no_write_count &&
+ count2 <= MAX_LOCKS);
}
if (count != lock->read_no_write_count)
{
@@ -286,7 +288,10 @@ static void check_locks(THR_LOCK *lock, const char *where,
if (lock->write.data->type == TL_WRITE_CONCURRENT_INSERT)
{
THR_LOCK_DATA *data;
- for (data=lock->write.data->next ; data ; data=data->next)
+ uint count= 0;
+ for (data=lock->write.data->next;
+ data && count < MAX_LOCKS;
+ data=data->next)
{
if (data->type != TL_WRITE_CONCURRENT_INSERT)
{
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 2d3775afb3a..f863ddd749e 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -398,9 +398,14 @@ else
echo "Installation of system tables failed! Examine the logs in"
echo "$ldata for more information."
echo
- echo "You can try to start the mysqld daemon with:"
+ echo "The problem could be conflicting information in an external"
+ echo "my.cnf files. You can ignore these by doing:"
echo
- echo " shell> $mysqld --skip-grant &"
+ echo " shell> /scripts/mysql_install_db --defaults-file=~/.my.cnf"
+ echo
+ echo "You can also try to start the mysqld daemon with:"
+ echo
+ echo " shell> $mysqld --skip-grant --general-log &"
echo
echo "and use the command line tool $bindir/mysql"
echo "to connect to the mysql database and look at the grant tables:"
@@ -408,9 +413,6 @@ else
echo " shell> $bindir/mysql -u root mysql"
echo " mysql> show tables"
echo
- echo "Try 'mysqld --help' if you have problems with paths. Using"
- echo "--general-log gives you a log in $ldata that may be helpful."
- echo
echo "The latest information about mysql_install_db is available at"
echo "http://kb.askmonty.org/v/installing-system-tables-mysql_install_db."
echo "MariaDB is hosted on launchpad; You can find the latest source and"
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 9ba6bd1e1b4..f81afa6b27b 100755..100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -58,9 +58,12 @@ SET (SQL_SOURCE
sp_rcontext.cc spatial.cc sql_acl.cc sql_analyse.cc sql_base.cc
sql_cache.cc sql_class.cc sql_client.cc sql_crypt.cc sql_crypt.h
sql_cursor.cc sql_db.cc sql_delete.cc sql_derived.cc sql_do.cc
- sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc
- sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc
- sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc
+ sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc
+ sql_lifo_buffer.h
+ sql_join_cache.h sql_join_cache.cc
+ sql_lex.cc sql_list.cc sql_load.cc sql_manager.cc
+ sql_map.cc sql_parse.cc sql_partition.cc sql_plugin.cc
+ sql_prepare.cc sql_rename.cc
debug_sync.cc debug_sync.h
sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc
sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc
@@ -73,7 +76,11 @@ SET (SQL_SOURCE
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc opt_table_elimination.cc
+ multi_range_read.cc
+ opt_subselect.cc
+ opt_index_cond_pushdown.cc
create_options.cc
+ sql_expression_cache.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 1c3ee09c0d5..05cb56bfab7 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -61,10 +61,12 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
ha_partition.h rpl_constants.h \
debug_sync.h \
opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
+ opt_subselect.h \
rpl_reporting.h \
log.h log_slow.h sql_show.h rpl_rli.h rpl_mi.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h \
lex.h lex_symbol.h sql_acl.h sql_crypt.h \
+ sql_lifo_buffer.h \
sql_repl.h slave.h rpl_filter.h rpl_injector.h \
log_event.h rpl_record.h \
log_event_old.h rpl_record_old.h \
@@ -79,7 +81,10 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
contributors.h sql_servers.h \
- create_options.h
+ multi_range_read.h sql_handler.h \
+ sql_join_cache.h \
+ create_options.h \
+ sql_expression_cache.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -93,6 +98,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
mysqld.cc password.c hash_filo.cc hostname.cc \
sql_connect.cc scheduler.cc sql_parse.cc \
set_var.cc sql_yacc.yy \
+ sql_join_cache.cc \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
sql_profile.cc \
sql_prepare.cc sql_error.cc sql_locale.cc \
@@ -102,7 +108,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
unireg.cc des_key_file.cc \
log_event.cc rpl_record.cc \
log_event_old.cc rpl_record_old.cc \
- discover.cc time.cc opt_range.cc opt_sum.cc \
+ discover.cc time.cc opt_range.cc opt_subselect.cc \
+ opt_sum.cc \
records.cc filesort.cc handler.cc \
ha_partition.cc \
debug_sync.cc \
@@ -125,7 +132,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc \
- opt_table_elimination.cc create_options.cc
+ opt_table_elimination.cc create_options.cc \
+ multi_range_read.cc \
+ opt_index_cond_pushdown.cc sql_expression_cache.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c client_plugin.c
@@ -153,7 +162,7 @@ BUILT_SOURCES = $(BUILT_MAINT_SRC) lex_hash.h link_sources
EXTRA_DIST = udf_example.c udf_example.def $(BUILT_MAINT_SRC) \
nt_servc.cc nt_servc.h \
message.mc message.h message.rc MSG00001.bin \
- CMakeLists.txt
+ CMakeLists.txt opt_range_mrr.cc
CLEANFILES = lex_hash.h sql_yacc.output link_sources
DISTCLEANFILES = $(EXTRA_PROGRAMS)
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index d1fa971847b..13a2f8cf7c2 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -212,7 +212,7 @@ mysql_event_fill_row(THD *thd,
Safety: this can only happen if someone started the server
and then altered mysql.event.
*/
- my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, MYF(0), table->alias,
+ my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, MYF(0), table->alias.c_ptr(),
(int) ET_FIELD_COUNT, table->s->fields);
DBUG_RETURN(TRUE);
}
@@ -896,7 +896,11 @@ Event_db_repository::find_named_event(LEX_STRING db, LEX_STRING name,
same fields.
*/
if (db.length > table->field[ET_FIELD_DB]->field_length ||
- name.length > table->field[ET_FIELD_NAME]->field_length)
+ name.length > table->field[ET_FIELD_NAME]->field_length ||
+ table->s->keys == 0 ||
+ table->key_info[0].key_parts != 2 ||
+ table->key_info[0].key_part[0].fieldnr != ET_FIELD_DB+1 ||
+ table->key_info[0].key_part[1].fieldnr != ET_FIELD_NAME+1)
DBUG_RETURN(TRUE);
table->field[ET_FIELD_DB]->store(db.str, db.length, &my_charset_bin);
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index d68dc8ef479..2a354fe6cfd 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -136,9 +136,9 @@ Event_queue::init_queue(THD *thd)
LOCK_QUEUE_DATA();
- if (init_queue_ex(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/,
- 0 /*max_on_top*/, event_queue_element_compare_q,
- NULL, EVENT_QUEUE_EXTENT))
+ if (::init_queue(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/,
+ 0 /*max_on_top*/, event_queue_element_compare_q,
+ NullS, 0, EVENT_QUEUE_EXTENT))
{
sql_print_error("Event Scheduler: Can't initialize the execution queue");
goto err;
@@ -325,11 +325,13 @@ void
Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern,
bool (*comparator)(LEX_STRING, Event_basic *))
{
- uint i= 0;
+ uint i;
DBUG_ENTER("Event_queue::drop_matching_events");
DBUG_PRINT("enter", ("pattern=%s", pattern.str));
- while (i < queue.elements)
+ for (i= queue_first_element(&queue) ;
+ i <= queue_last_element(&queue) ;
+ )
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
DBUG_PRINT("info", ("[%s.%s]?", et->dbname.str, et->name.str));
@@ -339,7 +341,8 @@ Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern,
The queue is ordered. If we remove an element, then all elements
after it will shift one position to the left, if we imagine it as
an array from left to the right. In this case we should not
- increment the counter and the (i < queue.elements) condition is ok.
+ increment the counter and the (i <= queue_last_element() condition
+ is ok.
*/
queue_remove(&queue, i);
delete et;
@@ -403,7 +406,9 @@ Event_queue::find_n_remove_event(LEX_STRING db, LEX_STRING name)
uint i;
DBUG_ENTER("Event_queue::find_n_remove_event");
- for (i= 0; i < queue.elements; ++i)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?", db.str, name.str,
@@ -441,7 +446,9 @@ Event_queue::recalculate_activation_times(THD *thd)
LOCK_QUEUE_DATA();
DBUG_PRINT("info", ("%u loaded events to be recalculated", queue.elements));
- for (i= 0; i < queue.elements; i++)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
((Event_queue_element*)queue_element(&queue, i))->compute_next_execution_time();
((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd);
@@ -454,16 +461,19 @@ Event_queue::recalculate_activation_times(THD *thd)
have removed all. The queue has been ordered in a way the disabled
events are at the end.
*/
- for (i= queue.elements; i > 0; i--)
+ for (i= queue_last_element(&queue);
+ (int) i >= (int) queue_first_element(&queue);
+ i--)
{
- Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1);
+ Event_queue_element *element=
+ (Event_queue_element*)queue_element(&queue, i);
if (element->status != Event_parse_data::DISABLED)
break;
/*
This won't cause queue re-order, because we remove
always the last element.
*/
- queue_remove(&queue, i - 1);
+ queue_remove(&queue, i);
delete element;
}
UNLOCK_QUEUE_DATA();
@@ -499,7 +509,9 @@ Event_queue::empty_queue()
sql_print_information("Event Scheduler: Purging the queue. %u events",
queue.elements);
/* empty the queue */
- for (i= 0; i < queue.elements; ++i)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
delete et;
@@ -525,7 +537,9 @@ Event_queue::dbug_dump_queue(time_t now)
uint i;
DBUG_ENTER("Event_queue::dbug_dump_queue");
DBUG_PRINT("info", ("Dumping queue . Elements=%u", queue.elements));
- for (i = 0; i < queue.elements; i++)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
et= ((Event_queue_element*)queue_element(&queue, i));
DBUG_PRINT("info", ("et: 0x%lx name: %s.%s", (long) et,
@@ -592,7 +606,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
continue;
}
- top= ((Event_queue_element*) queue_element(&queue, 0));
+ top= (Event_queue_element*) queue_top(&queue);
thd->set_current_time(); /* Get current time */
@@ -634,10 +648,10 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
top->dbname.str, top->name.str,
top->dropped? "Dropping.":"");
delete top;
- queue_remove(&queue, 0);
+ queue_remove_top(&queue);
}
else
- queue_replaced(&queue);
+ queue_replace_top(&queue);
dbug_dump_queue(thd->query_start());
break;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 8446fe75c8f..4d6636eedb2 100755..100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -100,7 +100,7 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et)
err_msg.append(err->msg, strlen(err->msg), system_charset_info);
DBUG_ASSERT(err->level < 3);
(sql_print_message_handlers[err->level])("%*s", err_msg.length(),
- err_msg.c_ptr());
+ err_msg.c_ptr_safe());
}
DBUG_VOID_RETURN;
}
diff --git a/sql/events.cc b/sql/events.cc
index 1b794edb5ec..3713266aaa6 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -480,7 +480,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
}
/* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
will be written into the binary log as the definer for the SQL thread. */
- ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
+ ret= write_bin_log(thd, TRUE, log_query.ptr(), log_query.length());
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
@@ -779,7 +779,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol)
protocol->store(et->name.str, et->name.length, system_charset_info);
protocol->store(sql_mode.str, sql_mode.length, system_charset_info);
protocol->store(tz_name->ptr(), tz_name->length(), system_charset_info);
- protocol->store(show_str.c_ptr(), show_str.length(),
+ protocol->store(show_str.ptr(), show_str.length(),
et->creation_ctx->get_client_cs());
protocol->store(et->creation_ctx->get_client_cs()->csname,
strlen(et->creation_ctx->get_client_cs()->csname),
diff --git a/sql/field.cc b/sql/field.cc
index 741df0cc270..4194c6a8939 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1536,9 +1536,9 @@ void Field::make_field(Send_field *field)
}
else
field->org_table_name= field->db_name= "";
- if (orig_table && orig_table->alias)
+ if (orig_table && orig_table->alias.ptr())
{
- field->table_name= orig_table->alias;
+ field->table_name= orig_table->alias.ptr();
field->org_col_name= field_name;
}
else
@@ -1706,8 +1706,8 @@ my_decimal *Field_str::val_decimal(my_decimal *decimal_value)
uint Field::fill_cache_field(CACHE_FIELD *copy)
{
uint store_length;
- copy->str=ptr;
- copy->length=pack_length();
+ copy->str= ptr;
+ copy->length= pack_length();
copy->field= this;
if (flags & BLOB_FLAG)
{
@@ -1719,9 +1719,15 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
(type() == MYSQL_TYPE_STRING && copy->length >= 4 &&
copy->length < 256))
{
- copy->type= CACHE_STRIPPED;
+ copy->type= CACHE_STRIPPED; /* Remove end space */
store_length= 2;
}
+ else if (type() == MYSQL_TYPE_VARCHAR)
+ {
+ copy->type= pack_length()-row_pack_length() == 1 ? CACHE_VARSTR1:
+ CACHE_VARSTR2;
+ store_length= 0;
+ }
else
{
copy->type= 0;
diff --git a/sql/field.h b/sql/field.h
index ca400caac59..b4dab7561ef 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -131,7 +131,8 @@ public:
*/
struct st_table *table; // Pointer for table
struct st_table *orig_table; // Pointer to original table
- const char **table_name, *field_name;
+ const char * const *table_name;
+ const char *field_name;
/** reference to the list of options or NULL */
engine_option_value *option_list;
void *option_struct; /* structure with parsed options */
@@ -551,10 +552,14 @@ public:
return (op_result == E_DEC_OVERFLOW);
}
int warn_if_overflow(int op_result);
+ void set_table_name(String *alias)
+ {
+ table_name= &alias->Ptr;
+ }
void init(TABLE *table_arg)
{
orig_table= table= table_arg;
- table_name= &table_arg->alias;
+ set_table_name(&table_arg->alias);
}
/* maximum possible display length */
@@ -585,6 +590,11 @@ public:
}
/* Hash value */
virtual void hash(ulong *nr, ulong *nr2);
+
+ /* Check whether the field can be used as a join attribute in hash join */
+ virtual bool hash_join_is_possible() { return TRUE; }
+ virtual bool eq_cmp_as_binary() { return TRUE; }
+
friend bool reopen_table(THD *,struct st_table *,bool);
friend int cre_myisam(char * name, register TABLE *form, uint options,
ulonglong auto_increment_value);
@@ -760,6 +770,7 @@ public:
my_decimal *val_decimal(my_decimal *);
virtual bool str_needs_quotes() { return TRUE; }
uint is_equal(Create_field *new_field);
+ bool eq_cmp_as_binary() { return test(flags & BINARY_FLAG); }
};
@@ -1904,6 +1915,7 @@ public:
uint size_of() const { return sizeof(*this); }
int reset(void) { return !maybe_null() || Field_blob::reset(); }
geometry_type get_geometry_type() { return geom_type; };
+ bool hash_join_is_possible() { return FALSE; }
};
#endif /*HAVE_SPATIAL*/
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 67ef4f95368..74ffee3f33e 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -449,7 +449,8 @@ static void do_varstring1(Copy_field *copy)
if (length > copy->to_length- 1)
{
length=copy->to_length - 1;
- if (copy->from_field->table->in_use->count_cuted_fields)
+ if (copy->from_field->table->in_use->count_cuted_fields &&
+ copy->to_field)
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
@@ -485,7 +486,8 @@ static void do_varstring2(Copy_field *copy)
if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
{
length=copy->to_length-HA_KEY_BLOB_LENGTH;
- if (copy->from_field->table->in_use->count_cuted_fields)
+ if (copy->from_field->table->in_use->count_cuted_fields &&
+ copy->to_field)
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
@@ -549,9 +551,9 @@ void Copy_field::set(uchar *to,Field *from)
do_copy= do_field_to_null_str;
}
else
- {
+ {
to_null_ptr= 0; // For easy debugging
- do_copy= do_field_eq;
+ do_copy= do_field_eq;
}
}
@@ -710,6 +712,9 @@ Copy_field::get_copy_func(Field *to,Field *from)
do_varstring1_mb) :
(from->charset()->mbmaxlen == 1 ? do_varstring2 :
do_varstring2_mb));
+ else
+ return (((Field_varstring*) from)->length_bytes == 1 ?
+ do_varstring1 : do_varstring2);
}
else if (to_length < from_length)
return (from->charset()->mbmaxlen == 1 ?
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 3f2e2e55046..1ee3972c4fd 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -543,11 +543,6 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
current_thd->variables.read_buff_size);
}
- if (quick_select)
- {
- if (select->quick->reset())
- DBUG_RETURN(HA_POS_ERROR);
- }
/* Remember original bitmaps */
save_read_set= sort_form->read_set;
@@ -561,9 +556,19 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
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);
sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set,
&sort_form->tmp_set);
+
+ if (quick_select)
+ {
+ if (select->quick->reset())
+ DBUG_RETURN(HA_POS_ERROR);
+ }
+
for (;;)
{
if (quick_select)
@@ -1161,7 +1166,9 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
{
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
- for (uint i= 0; i < queue->elements; ++i)
+ for (uint i= queue_first_element(queue);
+ i <= queue_last_element(queue);
+ i++)
{
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
if (bp->base + bp->max_keys * key_length == reuse->base)
@@ -1250,7 +1257,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
first_cmp_arg= (void*) &sort_length;
}
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
- (queue_compare) cmp, first_cmp_arg))
+ (queue_compare) cmp, first_cmp_arg, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
@@ -1287,7 +1294,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
error= 0; /* purecov: inspected */
goto end; /* purecov: inspected */
}
- queue_replaced(&queue); // Top element has been used
+ queue_replace_top(&queue); // Top element has been used
}
else
cmp= 0; // Not unique
@@ -1335,14 +1342,14 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
if (!(error= (int) read_to_buffer(from_file,buffpek,
rec_length)))
{
- VOID(queue_remove(&queue,0));
+ VOID(queue_remove_top(&queue));
reuse_freed_buff(&queue, buffpek, rec_length);
break; /* One buffer have been removed */
}
else if (error == -1)
goto err; /* purecov: inspected */
}
- queue_replaced(&queue); /* Top element has been replaced */
+ queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek= (BUFFPEK*) queue_top(&queue);
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index b7b7cdf1cce..a70e5aff996 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -8691,6 +8691,8 @@ ha_ndbcluster::null_value_index_search(KEY_MULTI_RANGE *ranges,
DBUG_RETURN(FALSE);
}
+#if 0
+/* MRR/NDB is disabled, for details see method declarations in ha_ndbcluster.h */
int
ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
KEY_MULTI_RANGE *ranges,
@@ -9063,6 +9065,7 @@ found_next:
m_multi_range_result_ptr += reclength;
DBUG_RETURN(0);
}
+#endif
int
ha_ndbcluster::setup_recattr(const NdbRecAttr* curr)
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index a17323d3fd6..7c9dba9e30e 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -259,10 +259,20 @@ class ha_ndbcluster: public handler
/**
* Multi range stuff
*/
+#if 0
+ /*
+ MRR/NDB is disabled in MariaDB. This is because in MariaDB, we've
+ backported
+ - the latest version of MRR interface (BKA needs this)
+ - the latest version of DS-MRR implementation
+ but didn't backport the latest version MRR/NDB implementation.
+
+ */
int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
KEY_MULTI_RANGE*ranges, uint range_count,
bool sorted, HANDLER_BUFFER *buffer);
int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
+#endif
bool null_value_index_search(KEY_MULTI_RANGE *ranges,
KEY_MULTI_RANGE *end_range,
HANDLER_BUFFER *buffer);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 1e462130a32..1ef78e30335 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1099,7 +1099,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
error != HA_ADMIN_ALREADY_DONE &&
error != HA_ADMIN_TRY_ALTER)
{
- print_admin_msg(thd, "error", table_share->db.str, table->alias,
+ print_admin_msg(thd, "error", table_share->db.str,
+ table->alias.c_ptr(),
opt_op_name[flag],
"Subpartition %s returned error",
sub_elem->partition_name);
@@ -1126,7 +1127,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
error != HA_ADMIN_ALREADY_DONE &&
error != HA_ADMIN_TRY_ALTER)
{
- print_admin_msg(thd, "error", table_share->db.str, table->alias,
+ print_admin_msg(thd, "error", table_share->db.str,
+ table->alias.c_ptr(),
opt_op_name[flag], "Partition %s returned error",
part_elem->partition_name);
}
@@ -2601,7 +2603,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
Initialize priority queue, initialized to reading forward.
*/
if ((error= init_queue(&m_queue, m_tot_parts, (uint) PARTITION_BYTES_IN_POS,
- 0, key_rec_cmp, (void*)this)))
+ 0, key_rec_cmp, (void*)this, 0, 0)))
goto err_handler;
/*
@@ -3903,6 +3905,7 @@ int ha_partition::index_init(uint inx, bool sorted)
m_part_spec.start_part= NO_CURRENT_PART_ID;
m_start_key.length= 0;
m_ordered= sorted;
+ m_ordered_scan_ongoing= FALSE;
m_curr_key_info[0]= table->key_info+inx;
if (m_pkey_is_clustered && table->s->primary_key != MAX_KEY)
{
@@ -4703,7 +4706,7 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
{
uint i;
- uint j= 0;
+ uint j= queue_first_element(&m_queue);
bool found= FALSE;
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
@@ -4719,6 +4722,12 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
int error;
handler *file= m_file[i];
+ /*
+ Reset null bits (to avoid valgrind warnings) and to give a default
+ value for not read null fields.
+ */
+ bfill(rec_buf_ptr, table->s->null_bytes, 255);
+
switch (m_index_scan_type) {
case partition_index_read:
error= file->ha_index_read_map(rec_buf_ptr,
@@ -4771,7 +4780,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
*/
queue_set_max_at_top(&m_queue, reverse_order);
queue_set_cmp_arg(&m_queue, (void*)m_curr_key_info);
- m_queue.elements= j;
+ m_queue.elements= j - queue_first_element(&m_queue);
queue_fix(&m_queue);
return_top_record(buf);
table->status= 0;
@@ -4842,7 +4851,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
if (error == HA_ERR_END_OF_FILE)
{
/* Return next buffered row */
- queue_remove(&m_queue, (uint) 0);
+ queue_remove_top(&m_queue);
if (m_queue.elements)
{
DBUG_PRINT("info", ("Record returned from partition %u (2)",
@@ -4854,7 +4863,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
}
DBUG_RETURN(error);
}
- queue_replaced(&m_queue);
+ queue_replace_top(&m_queue);
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %u", m_top_entry));
DBUG_RETURN(0);
@@ -4885,7 +4894,7 @@ int ha_partition::handle_ordered_prev(uchar *buf)
{
if (error == HA_ERR_END_OF_FILE)
{
- queue_remove(&m_queue, (uint) 0);
+ queue_remove_top(&m_queue);
if (m_queue.elements)
{
return_top_record(buf);
@@ -4897,7 +4906,7 @@ int ha_partition::handle_ordered_prev(uchar *buf)
}
DBUG_RETURN(error);
}
- queue_replaced(&m_queue);
+ queue_replace_top(&m_queue);
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
DBUG_RETURN(0);
diff --git a/sql/handler.cc b/sql/handler.cc
index e1808e8d460..b7e6b3a15ee 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2009,7 +2009,8 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
dummy_share.db.length= strlen(db);
dummy_share.table_name.str= (char*) alias;
dummy_share.table_name.length= strlen(alias);
- dummy_table.alias= alias;
+ dummy_table.alias.set(alias, dummy_share.table_name.length,
+ table_alias_charset);
file->change_table_ptr(&dummy_table, &dummy_share);
@@ -2855,11 +2856,12 @@ void handler::print_error(int error, myf errflag)
{
const char* engine= table_type();
if (temporary)
- my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine);
+ my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.c_ptr(),
+ engine);
else
{
SET_FATAL_ERROR;
- my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine);
+ my_error(ER_GET_ERRMSG, MYF(0), error, str.c_ptr(), engine);
}
}
else
@@ -4277,133 +4279,6 @@ void ha_binlog_log_query(THD *thd, handlerton *hton,
}
#endif
-/**
- Read the first row of a multi-range set.
-
- @param found_range_p Returns a pointer to the element in 'ranges' that
- corresponds to the returned row.
- @param ranges An array of KEY_MULTI_RANGE range descriptions.
- @param range_count Number of ranges in 'ranges'.
- @param sorted If result should be sorted per key.
- @param buffer A HANDLER_BUFFER for internal handler usage.
-
- @note
- - Record is read into table->record[0].
- - *found_range_p returns a valid value only if read_multi_range_first()
- returns 0.
- - Sorting is done within each range. If you want an overall sort, enter
- 'ranges' with sorted ranges.
-
- @retval
- 0 OK, found a row
- @retval
- HA_ERR_END_OF_FILE No rows in range
- @retval
- \# Error code
-*/
-int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
- KEY_MULTI_RANGE *ranges, uint range_count,
- bool sorted, HANDLER_BUFFER *buffer)
-{
- int result= HA_ERR_END_OF_FILE;
- DBUG_ENTER("handler::read_multi_range_first");
- multi_range_sorted= sorted;
- multi_range_buffer= buffer;
-
- table->mark_columns_used_by_index_no_reset(active_index, table->read_set);
- table->column_bitmaps_set(table->read_set, table->write_set);
-
- for (multi_range_curr= ranges, multi_range_end= ranges + range_count;
- multi_range_curr < multi_range_end;
- multi_range_curr++)
- {
- result= read_range_first(multi_range_curr->start_key.keypart_map ?
- &multi_range_curr->start_key : 0,
- multi_range_curr->end_key.keypart_map ?
- &multi_range_curr->end_key : 0,
- test(multi_range_curr->range_flag & EQ_RANGE),
- multi_range_sorted);
- if (result != HA_ERR_END_OF_FILE)
- break;
- }
-
- *found_range_p= multi_range_curr;
- DBUG_PRINT("exit",("result %d", result));
- DBUG_RETURN(result);
-}
-
-
-/**
- Read the next row of a multi-range set.
-
- @param found_range_p Returns a pointer to the element in 'ranges' that
- corresponds to the returned row.
-
- @note
- - Record is read into table->record[0].
- - *found_range_p returns a valid value only if read_multi_range_next()
- returns 0.
-
- @retval
- 0 OK, found a row
- @retval
- HA_ERR_END_OF_FILE No (more) rows in range
- @retval
- \# Error code
-*/
-int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
-{
- int result= 0;
- DBUG_ENTER("handler::read_multi_range_next");
-
- /* We should not be called after the last call returned EOF. */
- DBUG_ASSERT(multi_range_curr < multi_range_end);
-
- do
- {
- /* Save a call if there can be only one row in range. */
- if (multi_range_curr->range_flag != (UNIQUE_RANGE | EQ_RANGE))
- {
- result= read_range_next();
-
- /* On success or non-EOF errors jump to the end. */
- if (result != HA_ERR_END_OF_FILE)
- break;
- }
- else
- {
- if (was_semi_consistent_read())
- goto scan_it_again;
- /*
- We need to set this for the last range only, but checking this
- condition is more expensive than just setting the result code.
- */
- result= HA_ERR_END_OF_FILE;
- }
-
- multi_range_curr++;
-scan_it_again:
- /* Try the next range(s) until one matches a record. */
- for (; multi_range_curr < multi_range_end; multi_range_curr++)
- {
- result= read_range_first(multi_range_curr->start_key.keypart_map ?
- &multi_range_curr->start_key : 0,
- multi_range_curr->end_key.keypart_map ?
- &multi_range_curr->end_key : 0,
- test(multi_range_curr->range_flag & EQ_RANGE),
- multi_range_sorted);
- if (result != HA_ERR_END_OF_FILE)
- break;
- }
- }
- while ((result == HA_ERR_END_OF_FILE) &&
- (multi_range_curr < multi_range_end));
-
- *found_range_p= multi_range_curr;
- DBUG_PRINT("exit",("handler::read_multi_range_next: result %d", result));
- DBUG_RETURN(result);
-}
-
/**
Read first row between two ranges.
@@ -4507,7 +4382,7 @@ int handler::read_range_next()
int handler::compare_key(key_range *range)
{
int cmp;
- if (!range)
+ if (!range || in_range_check_pushed_down)
return 0; // No max range
cmp= key_cmp(range_key_part, range->key, range->length);
if (!cmp)
@@ -4516,6 +4391,23 @@ int handler::compare_key(key_range *range)
}
+/*
+ Same as compare_key() but doesn't check have in_range_check_pushed_down.
+ This is used by index condition pushdown implementation.
+*/
+
+int handler::compare_key2(key_range *range)
+{
+ int cmp;
+ if (!range)
+ return 0; // no max range
+ cmp= key_cmp(range_key_part, range->key, range->length);
+ if (!cmp)
+ cmp= key_compare_result_on_equal;
+ return cmp;
+}
+
+
int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
diff --git a/sql/handler.h b/sql/handler.h
index b7bc188b2ad..0878206b2ac 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -139,6 +139,9 @@
#define HA_HAS_NEW_CHECKSUM (LL(1) << 36)
#define HA_CAN_VIRTUAL_COLUMNS (LL(1) << 37)
+#define HA_MRR_CANT_SORT (LL(1) << 37)
+#define HA_RECORD_MUST_BE_CLEAN_ON_WRITE (LL(1) << 38)
+
/*
Set of all binlog flags. Currently only contain the capabilities
flags.
@@ -154,6 +157,15 @@
#define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
/*
+ Index scan will not return records in rowid order. Not guaranteed to be
+ set for unordered (e.g. HASH) indexes.
+*/
+#define HA_KEY_SCAN_NOT_ROR 128
+#define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */
+
+
+
+/*
bits in alter_table_flags:
*/
/*
@@ -206,12 +218,6 @@
#define HA_FAST_CHANGE_PARTITION (1L << 13)
#define HA_PARTITION_ONE_PHASE (1L << 14)
-/*
- Index scan will not return records in rowid order. Not guaranteed to be
- set for unordered (e.g. HASH) indexes.
-*/
-#define HA_KEY_SCAN_NOT_ROR 128
-
/* operations for disable/enable indexes */
#define HA_KEY_SWITCH_NONUNIQ 0
#define HA_KEY_SWITCH_ALL 1
@@ -1143,6 +1149,215 @@ typedef struct st_ha_check_opt
} HA_CHECK_OPT;
+/********************************************************************************
+ * MRR
+ ********************************************************************************/
+
+typedef void *range_seq_t;
+
+typedef struct st_range_seq_if
+{
+ /*
+ Get key information
+
+ SYNOPSIS
+ get_key_info()
+ init_params The seq_init_param parameter
+ length OUT length of the keys in this range sequence
+ map OUT key_part_map of the keys in this range sequence
+
+ DESCRIPTION
+ This function is set only when using HA_MRR_FIXED_KEY mode. In that mode,
+ all ranges are single-point equality ranges that use the same set of key
+ parts. This function allows the MRR implementation to get the length of
+ a key, and which keyparts it uses.
+ */
+ void (*get_key_info)(void *init_params, uint *length, key_part_map *map);
+
+ /*
+ Initialize the traversal of range sequence
+
+ SYNOPSIS
+ init()
+ init_params The seq_init_param parameter
+ n_ranges The number of ranges obtained
+ flags A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
+
+ RETURN
+ An opaque value to be used as RANGE_SEQ_IF::next() parameter
+ */
+ range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
+
+
+ /*
+ Get the next range in the range sequence
+
+ SYNOPSIS
+ next()
+ seq The value returned by RANGE_SEQ_IF::init()
+ range OUT Information about the next range
+
+ RETURN
+ FALSE - Ok, the range structure filled with info about the next range
+ TRUE - No more ranges
+ */
+ bool (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
+
+ /*
+ Check whether range_info orders to skip the next record
+
+ SYNOPSIS
+ skip_record()
+ seq The value returned by RANGE_SEQ_IF::init()
+ range_info Information about the next range
+ (Ignored if MRR_NO_ASSOCIATION is set)
+ rowid Rowid of the record to be checked (ignored if set to 0)
+
+ RETURN
+ 1 - Record with this range_info and/or this rowid shall be filtered
+ out from the stream of records returned by multi_range_read_next()
+ 0 - The record shall be left in the stream
+ */
+ bool (*skip_record) (range_seq_t seq, char *range_info, uchar *rowid);
+
+ /*
+ Check if the record combination matches the index condition
+ SYNOPSIS
+ skip_index_tuple()
+ seq The value returned by RANGE_SEQ_IF::init()
+ range_info Information about the next range
+
+ RETURN
+ 0 - The record combination satisfies the index condition
+ 1 - Otherwise
+ */
+ bool (*skip_index_tuple) (range_seq_t seq, char *range_info);
+} RANGE_SEQ_IF;
+
+typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, char *range_info);
+
+class COST_VECT
+{
+public:
+ double io_count; /* number of I/O */
+ double avg_io_cost; /* cost of an average I/O oper. */
+ double cpu_cost; /* cost of operations in CPU */
+ double mem_cost; /* cost of used memory */
+ double import_cost; /* cost of remote operations */
+
+ enum { IO_COEFF=1 };
+ enum { CPU_COEFF=1 };
+ enum { MEM_COEFF=1 };
+ enum { IMPORT_COEFF=1 };
+
+ COST_VECT() {} // keep gcc happy
+
+ double total_cost()
+ {
+ return IO_COEFF*io_count*avg_io_cost + CPU_COEFF * cpu_cost +
+ MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost;
+ }
+
+ void zero()
+ {
+ avg_io_cost= 1.0;
+ io_count= cpu_cost= mem_cost= import_cost= 0.0;
+ }
+
+ void multiply(double m)
+ {
+ io_count *= m;
+ cpu_cost *= m;
+ import_cost *= m;
+ /* Don't multiply mem_cost */
+ }
+
+ void add(const COST_VECT* cost)
+ {
+ double io_count_sum= io_count + cost->io_count;
+ add_io(cost->io_count, cost->avg_io_cost);
+ io_count= io_count_sum;
+ cpu_cost += cost->cpu_cost;
+ }
+ void add_io(double add_io_cnt, double add_avg_cost)
+ {
+ double io_count_sum= io_count + add_io_cnt;
+ avg_io_cost= (io_count * avg_io_cost +
+ add_io_cnt * add_avg_cost) / io_count_sum;
+ io_count= io_count_sum;
+ }
+
+ /*
+ To be used when we go from old single value-based cost calculations to
+ the new COST_VECT-based.
+ */
+ void convert_from_cost(double cost)
+ {
+ zero();
+ avg_io_cost= 1.0;
+ io_count= cost;
+ }
+};
+
+void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
+ COST_VECT *cost);
+
+/*
+ Indicates that all scanned ranges will be singlepoint (aka equality) ranges.
+ The ranges may not use the full key but all of them will use the same number
+ of key parts.
+*/
+#define HA_MRR_SINGLE_POINT 1
+#define HA_MRR_FIXED_KEY 2
+
+/*
+ Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
+ 'range' parameter.
+*/
+#define HA_MRR_NO_ASSOCIATION 4
+
+/*
+ The MRR user will provide ranges in key order, and MRR implementation
+ must return rows in key order.
+*/
+#define HA_MRR_SORTED 8
+
+/* MRR implementation doesn't have to retrieve full records */
+#define HA_MRR_INDEX_ONLY 16
+
+/*
+ The passed memory buffer is of maximum possible size, the caller can't
+ assume larger buffer.
+*/
+#define HA_MRR_LIMITS 32
+
+
+/*
+ Flag set <=> default MRR implementation is used
+ (The choice is made by **_info[_const]() function which may set this
+ flag. SQL layer remembers the flag value and then passes it to
+ multi_read_range_init().
+*/
+#define HA_MRR_USE_DEFAULT_IMPL 64
+
+/*
+ Used only as parameter to multi_range_read_info():
+ Flag set <=> the caller guarantees that the bounds of the scanned ranges
+ will not have NULL values.
+*/
+#define HA_MRR_NO_NULL_ENDPOINTS 128
+
+/*
+ The MRR user has materialized range keys somewhere in the user's buffer.
+ This can be used for optimization of the procedure that sorts these keys
+ since in this case key values don't have to be copied into the MRR buffer.
+
+ In other words, it is guaranteed that after RANGE_SEQ_IF::next() call the
+ pointer in range->start_key.key will point to a key value that will remain
+ there until the end of the MRR scan.
+*/
+#define HA_MRR_MATERIALIZED_KEYS 256
+
/*
This is a buffer area that the handler can use to store rows.
@@ -1153,8 +1368,8 @@ typedef struct st_ha_check_opt
typedef struct st_handler_buffer
{
- const uchar *buffer; /* Buffer one can start using */
- const uchar *buffer_end; /* End of buffer */
+ /* const? */uchar *buffer; /* Buffer one can start using */
+ /* const? */uchar *buffer_end; /* End of buffer */
uchar *end_of_used_area; /* End of area that was used by handler */
} HANDLER_BUFFER;
@@ -1185,11 +1400,16 @@ public:
time_t update_time;
uint block_size; /* index block size */
+ /*
+ number of buffer bytes that native mrr implementation needs,
+ */
+ uint mrr_length_per_rec;
+
ha_statistics():
data_file_length(0), max_data_file_length(0),
index_file_length(0), delete_length(0), auto_increment_value(0),
records(0), deleted(0), mean_rec_length(0), create_time(0),
- check_time(0), update_time(0), block_size(0)
+ check_time(0), update_time(0), block_size(0), mrr_length_per_rec(0)
{}
};
@@ -1228,11 +1448,18 @@ public:
ha_statistics stats;
- /** The following are for read_multi_range */
- bool multi_range_sorted;
- KEY_MULTI_RANGE *multi_range_curr;
- KEY_MULTI_RANGE *multi_range_end;
- HANDLER_BUFFER *multi_range_buffer;
+ /** MultiRangeRead-related members: */
+ range_seq_t mrr_iter; /* Interator to traverse the range sequence */
+ RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
+ HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
+ uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
+ /* TRUE <=> source MRR ranges and the output are ordered */
+ bool mrr_is_output_sorted;
+
+ /** TRUE <=> we're currently traversing a range in mrr_cur_range. */
+ bool mrr_have_range;
+ /** Current range (the one we're now returning rows from) */
+ KEY_MULTI_RANGE mrr_cur_range;
/** The following are for read_range() */
key_range save_end_range, *end_range;
@@ -1240,6 +1467,12 @@ public:
int key_compare_result_on_equal;
bool eq_range;
+ /*
+ TRUE <=> the engine guarantees that returned records are within the range
+ being scanned.
+ */
+ bool in_range_check_pushed_down;
+
uint errkey; /* Last dup key */
uint key_used_on_scan;
uint active_index;
@@ -1252,6 +1485,8 @@ public:
bool mark_trx_done;
bool cloned; /* 1 if this was created with clone */
const COND *pushed_cond;
+ Item *pushed_idx_cond;
+ uint pushed_idx_cond_keyno; /* The index which the above condition is for */
/**
next_insert_id is the next value which should be inserted into the
auto_increment column: in a inserting-multi-row statement (like INSERT
@@ -1291,11 +1526,14 @@ 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), in_range_check_pushed_down(FALSE),
+ key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
locked(FALSE), implicit_emptied(FALSE), mark_trx_done(FALSE), cloned(0),
- pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
+ pushed_cond(0), pushed_idx_cond(NULL),
+ pushed_idx_cond_keyno(MAX_KEY),
+ next_insert_id(0), insert_id_for_cur_row(0),
auto_inc_intervals_count(0)
{
reset_statistics();
@@ -1322,6 +1560,7 @@ public:
DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted)))
inited=INDEX;
+ end_range= NULL;
DBUG_RETURN(result);
}
int ha_index_end()
@@ -1329,6 +1568,7 @@ public:
DBUG_ENTER("ha_index_end");
DBUG_ASSERT(inited==INDEX);
inited=NONE;
+ end_range= NULL;
DBUG_RETURN(index_end());
}
/* This is called after index_init() if we need to do a index scan */
@@ -1607,16 +1847,27 @@ public:
inline int ha_index_first(uchar * buf);
inline int ha_index_last(uchar * buf);
inline int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
-
- virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
- KEY_MULTI_RANGE *ranges, uint range_count,
- bool sorted, HANDLER_BUFFER *buffer);
- virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
+ /*
+ TODO: should we make for those functions non-virtual ha_func_name wrappers,
+ too?
+ */
+ virtual 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);
+ virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf);
+ virtual int multi_range_read_next(char **range_info);
virtual int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
virtual int read_range_next();
int compare_key(key_range *range);
+ int compare_key2(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
void ft_end() { ft_handler=NULL; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
@@ -1938,6 +2189,7 @@ public:
Pops the top if condition stack, if stack is not empty.
*/
virtual void cond_pop() { return; };
+ virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
@@ -1957,6 +2209,18 @@ public:
LEX_STRING *engine_name() { return hton_name(ht); }
+ /*
+ @brief
+ Check whether the engine supports virtual columns
+
+ @retval
+ FALSE if the engine does not support virtual columns
+ @retval
+ TRUE if the engine supports virtual columns
+ */
+ virtual bool check_if_supported_virtual_columns(void) { return FALSE;}
+
+ TABLE* get_table() { return table; }
protected:
/* deprecated, don't use in new engines */
inline void ha_statistic_increment(ulong SSV::*offset) const { }
@@ -2155,6 +2419,9 @@ public:
{ return ht; }
};
+#include "multi_range_read.h"
+
+bool key_uses_partial_cols(TABLE *table, uint keyno);
/* Some extern variables used with handlers */
diff --git a/sql/item.cc b/sql/item.cc
index 2fb2f5e91e2..310e6994c7d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -28,6 +28,9 @@
const String my_null_string("NULL", 4, default_charset_info);
+static int save_field_in_field(Field *from, bool *null_value,
+ Field *to, bool no_conversions);
+
/****************************************************************************/
/* Hybrid_type_traits {_real} */
@@ -374,8 +377,8 @@ int Item::save_str_value_in_field(Field *field, String *result)
Item::Item():
- rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
- is_autogenerated_name(TRUE),
+ is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0),
+ fixed(0), is_autogenerated_name(TRUE),
collation(&my_charset_bin, DERIVATION_COERCIBLE)
{
marker= 0;
@@ -412,6 +415,7 @@ Item::Item():
tables.
*/
Item::Item(THD *thd, Item *item):
+ is_expensive_cache(-1),
rsize(0),
str_value(item->str_value),
name(item->name),
@@ -543,6 +547,36 @@ Item* Item::transform(Item_transformer transformer, uchar *arg)
}
+/**
+ Create and set up an expression cache for this item
+
+ @param thd Thread handle
+ @param depends_on List of the expression parameters
+
+ @details
+ The function creates an expression cache for an item and its parameters
+ specified by the 'depends_on' list. Then the expression cache is placed
+ into a cache wrapper that is returned as the result of the function.
+
+ @returns
+ A pointer to created wrapper item if successful, NULL - otherwise
+*/
+
+Item* Item::set_expr_cache(THD *thd, List<Item *> &depends_on)
+{
+ DBUG_ENTER("Item::set_expr_cache");
+ Item_cache_wrapper *wrapper;
+ if ((wrapper= new Item_cache_wrapper(this)) &&
+ !wrapper->fix_fields(thd, (Item**)&wrapper))
+ {
+ if (wrapper->set_cache(thd, depends_on))
+ DBUG_RETURN(NULL);
+ DBUG_RETURN(wrapper);
+ }
+ DBUG_RETURN(NULL);
+}
+
+
Item_ident::Item_ident(Name_resolution_context *context_arg,
const char *db_name_arg,const char *table_name_arg,
const char *field_name_arg)
@@ -551,7 +585,7 @@ Item_ident::Item_ident(Name_resolution_context *context_arg,
db_name(db_name_arg), table_name(table_name_arg),
field_name(field_name_arg),
alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
- cached_table(0), depended_from(0)
+ cached_table(0), depended_from(0), can_be_depended(TRUE)
{
name = (char*) field_name_arg;
}
@@ -563,7 +597,7 @@ Item_ident::Item_ident(TABLE_LIST *view_arg, const char *field_name_arg)
db_name(NullS), table_name(view_arg->alias),
field_name(field_name_arg),
alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
- cached_table(NULL), depended_from(NULL)
+ cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
{
name = (char*) field_name_arg;
}
@@ -585,7 +619,8 @@ Item_ident::Item_ident(THD *thd, Item_ident *item)
alias_name_used(item->alias_name_used),
cached_field_index(item->cached_field_index),
cached_table(item->cached_table),
- depended_from(item->depended_from)
+ depended_from(item->depended_from),
+ can_be_depended(item->can_be_depended)
{}
void Item_ident::cleanup()
@@ -603,7 +638,8 @@ void Item_ident::cleanup()
db_name= orig_db_name;
table_name= orig_table_name;
field_name= orig_field_name;
- depended_from= 0;
+ /* Store if this Item was depended */
+ can_be_depended= test(depended_from);
DBUG_VOID_RETURN;
}
@@ -652,6 +688,16 @@ bool Item_field::collect_item_field_processor(uchar *arg)
}
+bool Item_field::add_field_to_set_processor(uchar *arg)
+{
+ DBUG_ENTER("Item_field::add_field_to_set_processor");
+ DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname"));
+ TABLE *table= (TABLE *) arg;
+ if (field->table == table)
+ bitmap_set_bit(&table->tmp_set, field->field_index);
+ DBUG_RETURN(FALSE);
+}
+
/**
Check if an Item_field references some field from a list of fields.
@@ -737,7 +783,8 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
}
if (cs->ctype)
{
- uint orig_len= length;
+ const char *str_start= str;
+
/*
This will probably need a better implementation in the future:
a function in CHARSET_INFO structure.
@@ -747,16 +794,20 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
length--;
str++;
}
- if (orig_len != length && !is_autogenerated_name)
+ if (str != str_start && !is_autogenerated_name)
{
+ char buff[SAFE_NAME_LEN];
+ strmake(buff, str_start,
+ min(sizeof(buff)-1, length + (int) (str-str_start)));
+
if (length == 0)
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_NAME_BECOMES_EMPTY, ER(ER_NAME_BECOMES_EMPTY),
- str + length - orig_len);
+ buff);
else
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES),
- str + length - orig_len);
+ buff);
}
}
if (!my_charset_same(cs, system_charset_info))
@@ -1416,7 +1467,7 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
/* An item of type Item_sum is registered <=> ref_by != 0 */
if (type() == SUM_FUNC_ITEM && skip_registered &&
((Item_sum *) this)->ref_by)
- return;
+ return;
if ((type() != SUM_FUNC_ITEM && with_sum_func) ||
(type() == FUNC_ITEM &&
(((Item_func *) this)->functype() == Item_func::ISNOTNULLTEST_FUNC ||
@@ -1737,7 +1788,10 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname,
subselect transformation does not happen in view_prepare_mode
and thus val_...() methods can not be called for const items.
*/
- bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM &&
+ bool resolve_const= (((*arg)->type() == Item::SUBSELECT_ITEM ||
+ ((*arg)->get_cached_item() &&
+ (*arg)->get_cached_item()->type() ==
+ Item::SUBSELECT_ITEM)) &&
thd->lex->view_prepare_mode) ? FALSE : TRUE;
conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const);
}
@@ -1963,7 +2017,7 @@ void Item_field::reset_field(Field *f)
bool Item_field::enumerate_field_refs_processor(uchar *arg)
{
Field_enumerator *fe= (Field_enumerator*)arg;
- fe->visit_field(field);
+ fe->visit_field(this);
return FALSE;
}
@@ -2123,6 +2177,12 @@ bool Item_field::get_time(MYSQL_TIME *ltime)
return 0;
}
+void Item_field::save_result(Field *to)
+{
+ save_field_in_field(result_field, &null_value, to, TRUE);
+}
+
+
double Item_field::val_result()
{
if ((null_value=result_field->is_null()))
@@ -2216,6 +2276,24 @@ table_map Item_field::used_tables() const
}
+void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ if (new_parent == depended_from)
+ depended_from= NULL;
+ Name_resolution_context *ctx= new Name_resolution_context();
+ ctx->outer_context= NULL; // We don't build a complete name resolver
+ ctx->table_list= NULL; // We rely on first_name_resolution_table instead
+ ctx->select_lex= new_parent;
+ ctx->first_name_resolution_table= context->first_name_resolution_table;
+ ctx->last_name_resolution_table= context->last_name_resolution_table;
+ ctx->error_processor= context->error_processor;
+ ctx->error_processor_data= context->error_processor_data;
+ ctx->resolve_in_select_list= context->resolve_in_select_list;
+ ctx->security_ctx= context->security_ctx;
+ this->context=ctx;
+}
+
+
Item *Item_field::get_tmp_table_item(THD *thd)
{
Item_field *new_item= new Item_field(thd, this);
@@ -2495,14 +2573,12 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
tmp= my_strntod(cs, (char*) cptr, end - cptr, &end, &error);
if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
{
- /*
- We can use str_value.ptr() here as Item_string is gurantee to put an
- end \0 here.
- */
+ char buff[80];
+ strmake(buff, cptr, min(sizeof(buff)-1, (size_t) (org_end-cptr)));
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
- cptr);
+ buff);
}
return tmp;
}
@@ -2511,8 +2587,10 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
double Item_string::val_real()
{
DBUG_ASSERT(fixed == 1);
- return double_from_string_with_check (str_value.charset(), str_value.ptr(),
- (char *) str_value.ptr() + str_value.length());
+ return double_from_string_with_check(str_value.charset(),
+ str_value.ptr(),
+ (char *) str_value.ptr() +
+ str_value.length());
}
@@ -3570,6 +3648,15 @@ bool Item::fix_fields(THD *thd, Item **ref)
return FALSE;
}
+
+void Item_ref_null_helper::save_val(Field *to)
+{
+ DBUG_ASSERT(fixed == 1);
+ (*ref)->save_val(to);
+ owner->was_null|= null_value= (*ref)->null_value;
+}
+
+
double Item_ref_null_helper::val_real()
{
DBUG_ASSERT(fixed == 1);
@@ -3633,7 +3720,7 @@ bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, uint fuzzydate)
substitution)
*/
-static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
+static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
Item_ident *resolved_item,
Item_ident *mark_item)
{
@@ -3642,9 +3729,11 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
const char *table_name= (resolved_item->table_name ?
resolved_item->table_name : "");
/* store pointer on SELECT_LEX from which item is dependent */
- if (mark_item)
+ if (mark_item && mark_item->can_be_depended)
mark_item->depended_from= last;
- current->mark_as_dependent(last, resolved_item);
+ if (current->mark_as_dependent(thd, last, /** resolved_item psergey-thu
+ **/mark_item))
+ return TRUE;
if (thd->lex->describe & DESCRIBE_EXTENDED)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
@@ -3654,6 +3743,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
resolved_item->field_name,
current->select_number, last->select_number);
}
+ return FALSE;
}
@@ -4105,6 +4195,9 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
+ context->select_lex->
+ register_dependency_item(last_checked_context->select_lex,
+ reference);
/*
A reference to a view field had been found and we
substituted it instead of this Item (find_field_in_tables
@@ -4203,8 +4296,12 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
return -1;
mark_as_dependent(thd, last_checked_context->select_lex,
- context->select_lex, this,
+ context->select_lex, rf,
rf);
+ context->select_lex->
+ register_dependency_item(last_checked_context->select_lex,
+ reference);
+
return 0;
}
else
@@ -4212,6 +4309,9 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex,
this, (Item_ident*)*reference);
+ context->select_lex->
+ register_dependency_item(last_checked_context->select_lex,
+ reference);
if (last_checked_context->select_lex->having_fix_field)
{
Item_ref *rf;
@@ -4518,6 +4618,7 @@ void Item_field::cleanup()
{
DBUG_ENTER("Item_field::cleanup");
Item_ident::cleanup();
+ depended_from= NULL;
/*
Even if this object was created by direct link to field in setup_wild()
it will be linked correctly next time by name of field and table alias.
@@ -4746,7 +4847,7 @@ Item *Item_field::replace_equal_field(uchar *arg)
return this;
return const_item;
}
- Item_field *subst= item_equal->get_first();
+ Item_field *subst= item_equal->get_first(this);
if (subst && field->table != subst->field->table && !field->eq(subst->field))
return subst;
}
@@ -5076,47 +5177,69 @@ void Item_field::make_field(Send_field *tmp_field)
/**
- Set a field's value from a item.
-*/
+ Save a field value in another field
-void Item_field::save_org_in_field(Field *to)
-{
- if (field->is_null())
- {
- null_value=1;
- set_field_to_null_with_conversions(to, 1);
- }
- else
- {
- to->set_notnull();
- field_conv(to,field);
- null_value=0;
- }
-}
+ @param from Field to take the value from
+ @param [out] null_value Pointer to the null_value flag to set
+ @param to Field to save the value in
+ @param no_conversions How to deal with NULL value
-int Item_field::save_in_field(Field *to, bool no_conversions)
+ @details
+ The function takes the value of the field 'from' and, if this value
+ is not null, it saves in the field 'to' setting off the flag referenced
+ by 'null_value'. Otherwise this flag is set on and field 'to' is
+ also set to null possibly with conversion.
+
+ @note
+ This function is used by the functions Item_field::save_in_field,
+ Item_field::save_org_in_field and Item_ref::save_in_field
+
+ @retval FALSE OK
+ @retval TRUE Error
+
+*/
+
+static int save_field_in_field(Field *from, bool *null_value,
+ Field *to, bool no_conversions)
{
int res;
- if (result_field->is_null())
+ DBUG_ENTER("save_field_in_field");
+ if (from->is_null())
{
- null_value=1;
- return set_field_to_null_with_conversions(to, no_conversions);
+ (*null_value)= 1;
+ DBUG_RETURN(set_field_to_null_with_conversions(to, no_conversions));
}
to->set_notnull();
/*
If we're setting the same field as the one we're reading from there's
nothing to do. This can happen in 'SET x = x' type of scenarios.
- */
- if (to == result_field)
+ */
+ if (to == from)
{
- null_value=0;
- return 0;
+ (*null_value)= 0;
+ DBUG_RETURN(0);
}
- res= field_conv(to,result_field);
- null_value=0;
- return res;
+ res= field_conv(to, from);
+ (*null_value)= 0;
+ DBUG_RETURN(res);
+}
+
+
+/**
+ Set a field's value from a item.
+*/
+
+void Item_field::save_org_in_field(Field *to)
+{
+ save_field_in_field(field, &null_value, to, TRUE);
+}
+
+
+int Item_field::save_in_field(Field *to, bool no_conversions)
+{
+ return save_field_in_field(result_field, &null_value, to, no_conversions);
}
@@ -5789,6 +5912,35 @@ Item_ref::Item_ref(Name_resolution_context *context_arg,
set_properties();
}
+/*
+ A Field_enumerator-compatible class that invokes mark_as_dependent() for
+ each field that is a reference to some ancestor of current_select.
+*/
+class Dependency_marker: public Field_enumerator
+{
+public:
+ THD *thd;
+ st_select_lex *current_select;
+ virtual void visit_field(Item_field *item)
+ {
+ // Find which select the field is in. This is achieved by walking up
+ // the select tree and looking for the table of interest.
+ st_select_lex *sel;
+ for (sel= current_select; sel; sel= sel->outer_select())
+ {
+ TABLE_LIST *tbl;
+ for (tbl= sel->leaf_tables; tbl; tbl= tbl->next_leaf)
+ {
+ if (tbl->table == item->field->table)
+ {
+ if (sel != current_select)
+ mark_as_dependent(thd, sel, current_select, item, item);
+ return;
+ }
+ }
+ }
+ }
+};
Item_ref::Item_ref(TABLE_LIST *view_arg, Item **item,
const char *field_name_arg, bool alias_name_used_arg)
@@ -5977,6 +6129,9 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
refer_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
+ context->select_lex->
+ register_dependency_item(last_checked_context->select_lex,
+ reference);
/*
view reference found, we substituted it instead of this
Item, so can quit
@@ -6026,7 +6181,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
goto error;
thd->change_item_tree(reference, fld);
mark_as_dependent(thd, last_checked_context->select_lex,
- thd->lex->current_select, this, fld);
+ thd->lex->current_select, fld, fld);
+ context->select_lex->
+ register_dependency_item(last_checked_context->select_lex,
+ reference);
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
@@ -6050,6 +6208,9 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(*ref && (*ref)->fixed);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex, this, this);
+ context->select_lex->
+ register_dependency_item(last_checked_context->select_lex,
+ reference);
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
@@ -6062,6 +6223,24 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
last_checked_context->select_lex->nest_level);
}
}
+ else
+ {
+ if (depended_from && reference)
+ {
+ DBUG_ASSERT(context->select_lex != depended_from);
+ context->select_lex->register_dependency_item(depended_from, reference);
+ }
+ /*
+ It could be that we're referring to something that's in ancestor selects.
+ We must make an appropriate mark_as_dependent() call for each such
+ outside reference.
+ */
+ Dependency_marker dep_marker;
+ dep_marker.current_select= current_sel;
+ dep_marker.thd= thd;
+ (*ref)->walk(&Item::enumerate_field_refs_processor, FALSE,
+ (uchar*)&dep_marker);
+ }
DBUG_ASSERT(*ref);
/*
@@ -6241,6 +6420,25 @@ bool Item_ref::val_bool_result()
}
+void Item_ref::save_result(Field *to)
+{
+ if (result_field)
+ {
+ save_field_in_field(result_field, &null_value, to, TRUE);
+ return;
+ }
+ (*ref)->save_result(to);
+ null_value= (*ref)->null_value;
+}
+
+
+void Item_ref::save_val(Field *to)
+{
+ (*ref)->save_result(to);
+ null_value= (*ref)->null_value;
+}
+
+
double Item_ref::val_real()
{
DBUG_ASSERT(fixed);
@@ -6358,6 +6556,13 @@ void Item_ref_null_helper::print(String *str, enum_query_type query_type)
}
+void Item_direct_ref::save_val(Field *to)
+{
+ (*ref)->save_val(to);
+ null_value=(*ref)->null_value;
+}
+
+
double Item_direct_ref::val_real()
{
double tmp=(*ref)->val_real();
@@ -6410,6 +6615,385 @@ bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
}
+Item_cache_wrapper::~Item_cache_wrapper()
+{
+ delete expr_cache;
+ /* expr_value is Item so it will be destroyed from list of Items */
+}
+
+
+Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
+:orig_item(item_arg), expr_cache(NULL), expr_value(NULL)
+{
+ DBUG_ASSERT(orig_item->fixed);
+ max_length= orig_item->max_length;
+ maybe_null= orig_item->maybe_null;
+ decimals= orig_item->decimals;
+ collation.set(orig_item->collation);
+ with_sum_func= orig_item->with_sum_func;
+ unsigned_flag= orig_item->unsigned_flag;
+ name= item_arg->name;
+ name_length= item_arg->name_length;
+
+ if ((expr_value= Item_cache::get_cache(orig_item)))
+ expr_value->setup(orig_item);
+
+ fixed= 1;
+}
+
+
+void Item_cache_wrapper::print(String *str, enum_query_type query_type)
+{
+ str->append(func_name());
+ if (expr_cache)
+ expr_cache->print(str, query_type);
+ else
+ str->append(STRING_WITH_LEN("<<DISABLED>>"));
+ str->append('(');
+ orig_item->print(str, query_type);
+ str->append(')');
+}
+
+
+/**
+ Prepare the expression cache wrapper (do nothing)
+
+ @retval FALSE OK
+*/
+
+bool Item_cache_wrapper::fix_fields(THD *thd __attribute__((unused)),
+ Item **it __attribute__((unused)))
+{
+ DBUG_ASSERT(orig_item->fixed);
+ DBUG_ASSERT(fixed);
+ return FALSE;
+}
+
+
+/**
+ Clean the expression cache wrapper up before reusing it.
+*/
+
+void Item_cache_wrapper::cleanup()
+{
+ delete expr_cache;
+ expr_cache= 0;
+ // expr_value is Item so it will be destroyed from list of Items
+ expr_value= 0;
+}
+
+
+/**
+ Create an expression cache that uses a temporary table
+
+ @param thd Thread handle
+ @param depends_on Parameters of the expression to create cache for
+
+ @details
+ The function takes 'depends_on' as the list of all parameters for
+ the expression wrapped into this object and creates an expression
+ cache in a temporary table containing the field for the parameters
+ and the result of the expression.
+
+ @retval FALSE OK
+ @retval TRUE Error
+*/
+
+bool Item_cache_wrapper::set_cache(THD *thd, List<Item*> &depends_on)
+{
+ DBUG_ENTER("Item_cache_wrapper::set_cache");
+ expr_cache= new Expression_cache_tmptable(thd, depends_on, expr_value);
+ DBUG_RETURN(expr_cache == NULL);
+}
+
+
+/**
+ Check if the current values of the parameters are in the expression cache
+
+ @details
+ The function checks whether the current set of the parameters of the
+ referenced item can be found in the expression cache. If so the function
+ returns the item by which the result of the expression can be easily
+ extracted from the cache with the corresponding val_* method.
+
+ @retval NULL - parameters are not in the cache
+ @retval <item*> - item providing the result of the expression found in cache
+*/
+
+Item *Item_cache_wrapper::check_cache()
+{
+ DBUG_ENTER("Item_cache_wrapper::check_cache");
+ if (expr_cache)
+ {
+ Expression_cache_tmptable::result res;
+ Item *cached_value;
+ res= expr_cache->check_value(&cached_value);
+ if (res == Expression_cache_tmptable::HIT)
+ DBUG_RETURN(cached_value);
+ }
+ DBUG_RETURN(NULL);
+}
+
+
+/**
+ Get the value of the cached expression and put it in the cache
+*/
+
+inline void Item_cache_wrapper::cache()
+{
+ expr_value->store(orig_item);
+ expr_value->cache_value();
+ expr_cache->put_value(expr_value); // put in expr_cache
+}
+
+
+/**
+ Get the value of the possibly cached item into the field.
+*/
+
+void Item_cache_wrapper::save_val(Field *to)
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::val_int");
+ if (!expr_cache)
+ {
+ orig_item->save_val(to);
+ null_value= orig_item->null_value;
+ DBUG_VOID_RETURN;
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ cached_value->save_val(to);
+ null_value= cached_value->null_value;
+ DBUG_VOID_RETURN;
+ }
+ cache();
+ null_value= expr_value->null_value;
+ expr_value->save_val(to);
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Get the integer value of the possibly cached item.
+*/
+
+longlong Item_cache_wrapper::val_int()
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::val_int");
+ if (!expr_cache)
+ {
+ longlong tmp= orig_item->val_int();
+ null_value= orig_item->null_value;
+ DBUG_RETURN(tmp);
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ longlong tmp= cached_value->val_int();
+ null_value= cached_value->null_value;
+ DBUG_RETURN(tmp);
+ }
+ cache();
+ null_value= expr_value->null_value;
+ DBUG_RETURN(expr_value->val_int());
+}
+
+
+/**
+ Get the real value of the possibly cached item
+*/
+
+double Item_cache_wrapper::val_real()
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::val_real");
+ if (!expr_cache)
+ {
+ double tmp= orig_item->val_real();
+ null_value= orig_item->null_value;
+ DBUG_RETURN(tmp);
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ double tmp= cached_value->val_real();
+ null_value= cached_value->null_value;
+ DBUG_RETURN(tmp);
+ }
+ cache();
+ null_value= expr_value->null_value;
+ DBUG_RETURN(expr_value->val_real());
+}
+
+
+/**
+ Get the string value of the possibly cached item
+*/
+
+String *Item_cache_wrapper::val_str(String* str)
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::val_str");
+ if (!expr_cache)
+ {
+ String *tmp= orig_item->val_str(str);
+ null_value= orig_item->null_value;
+ DBUG_RETURN(tmp);
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ String *tmp= cached_value->val_str(str);
+ null_value= cached_value->null_value;
+ DBUG_RETURN(tmp);
+ }
+ cache();
+ if ((null_value= expr_value->null_value))
+ DBUG_RETURN(NULL);
+ DBUG_RETURN(expr_value->val_str(str));
+}
+
+
+/**
+ Get the decimal value of the possibly cached item
+*/
+
+my_decimal *Item_cache_wrapper::val_decimal(my_decimal* decimal_value)
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::val_decimal");
+ if (!expr_cache)
+ {
+ my_decimal *tmp= orig_item->val_decimal(decimal_value);
+ null_value= orig_item->null_value;
+ DBUG_RETURN(tmp);
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ my_decimal *tmp= cached_value->val_decimal(decimal_value);
+ null_value= cached_value->null_value;
+ DBUG_RETURN(tmp);
+ }
+ cache();
+ if ((null_value= expr_value->null_value))
+ DBUG_RETURN(NULL);
+ DBUG_RETURN(expr_value->val_decimal(decimal_value));
+}
+
+
+/**
+ Get the boolean value of the possibly cached item
+*/
+
+bool Item_cache_wrapper::val_bool()
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::val_bool");
+ if (!expr_cache)
+ {
+ bool tmp= orig_item->val_bool();
+ null_value= orig_item->null_value;
+ DBUG_RETURN(tmp);
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ bool tmp= cached_value->val_bool();
+ null_value= cached_value->null_value;
+ DBUG_RETURN(tmp);
+ }
+ cache();
+ null_value= expr_value->null_value;
+ DBUG_RETURN(expr_value->val_bool());
+}
+
+
+/**
+ Check for NULL the value of the possibly cached item
+*/
+
+bool Item_cache_wrapper::is_null()
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::is_null");
+ if (!expr_cache)
+ {
+ bool tmp= orig_item->is_null();
+ null_value= orig_item->null_value;
+ DBUG_RETURN(tmp);
+ }
+
+ if ((cached_value= check_cache()))
+ {
+ bool tmp= cached_value->is_null();
+ null_value= cached_value->null_value;
+ DBUG_RETURN(tmp);
+ }
+ cache();
+ DBUG_RETURN((null_value= expr_value->null_value));
+}
+
+
+/**
+ Get the date value of the possibly cached item
+*/
+
+bool Item_cache_wrapper::get_date(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::get_date");
+ if (!expr_cache)
+ DBUG_RETURN((null_value= orig_item->get_date(ltime, fuzzydate)));
+
+ if ((cached_value= check_cache()))
+ DBUG_RETURN((null_value= cached_value->get_date(ltime, fuzzydate)));
+
+ cache();
+ DBUG_RETURN((null_value= expr_value->get_date(ltime, fuzzydate)));
+}
+
+
+/**
+ Get the time value of the possibly cached item
+*/
+
+bool Item_cache_wrapper::get_time(MYSQL_TIME *ltime)
+{
+ Item *cached_value;
+ DBUG_ENTER("Item_cache_wrapper::get_time");
+ if (!expr_cache)
+ DBUG_RETURN((null_value= orig_item->get_time(ltime)));
+
+ if ((cached_value= check_cache()))
+ DBUG_RETURN((null_value= cached_value->get_time(ltime)));
+
+ cache();
+ DBUG_RETURN((null_value= expr_value->get_time(ltime)));
+}
+
+
+int Item_cache_wrapper::save_in_field(Field *to, bool no_conversions)
+{
+ int res;
+ DBUG_ASSERT(!result_field);
+ res= orig_item->save_in_field(to, no_conversions);
+ null_value= orig_item->null_value;
+ return res;
+}
+
+
+Item* Item_cache_wrapper::get_tmp_table_item(THD *thd_arg)
+{
+ if (!orig_item->with_sum_func && !orig_item->const_item())
+ return new Item_field(result_field);
+ return copy_or_same(thd_arg);
+}
+
+
/**
Prepare referenced field then call usual Item_direct_ref::fix_fields .
@@ -6478,6 +7062,23 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
}
+void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ if (depended_from == new_parent)
+ {
+ *ref= outer_ref;
+ (*ref)->fix_after_pullout(new_parent, ref);
+ }
+}
+
+void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
+{
+ (*ref)->fix_after_pullout(new_parent, ref);
+ if (depended_from == new_parent)
+ depended_from= NULL;
+}
+
+
/**
Mark references from inner selects used in group by clause
@@ -7156,8 +7757,11 @@ void Item_cache_int::store_longlong(Item *item, longlong val_arg)
String *Item_cache_int::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
+ }
str->set(value, default_charset());
return str;
}
@@ -7166,8 +7770,11 @@ String *Item_cache_int::val_str(String *str)
my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
+ }
int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val);
return decimal_val;
}
@@ -7175,16 +7782,22 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
double Item_cache_int::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0.0;
+ }
return (double) value;
}
longlong Item_cache_int::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0;
+ }
return value;
}
@@ -7202,16 +7815,22 @@ bool Item_cache_real::cache_value()
double Item_cache_real::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0.0;
+ }
return value;
}
longlong Item_cache_real::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0;
+ }
return (longlong) rint(value);
}
@@ -7219,8 +7838,11 @@ longlong Item_cache_real::val_int()
String* Item_cache_real::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
+ }
str->set_real(value, decimals, default_charset());
return str;
}
@@ -7229,8 +7851,11 @@ String* Item_cache_real::val_str(String *str)
my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
+ }
double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
return decimal_val;
}
@@ -7251,8 +7876,11 @@ double Item_cache_decimal::val_real()
{
DBUG_ASSERT(fixed);
double res;
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0.0;
+ }
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
return res;
}
@@ -7261,8 +7889,11 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT(fixed);
longlong res;
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0;
+ }
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
return res;
}
@@ -7270,8 +7901,11 @@ longlong Item_cache_decimal::val_int()
String* Item_cache_decimal::val_str(String *str)
{
DBUG_ASSERT(fixed);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
+ }
my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
&decimal_value);
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str);
@@ -7281,8 +7915,11 @@ String* Item_cache_decimal::val_str(String *str)
my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
{
DBUG_ASSERT(fixed);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
+ }
return &decimal_value;
}
@@ -7317,12 +7954,13 @@ double Item_cache_str::val_real()
DBUG_ASSERT(fixed == 1);
int err_not_used;
char *end_not_used;
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0.0;
- if (value)
- return my_strntod(value->charset(), (char*) value->ptr(),
- value->length(), &end_not_used, &err_not_used);
- return (double) 0;
+ }
+ return my_strntod(value->charset(), (char*) value->ptr(),
+ value->length(), &end_not_used, &err_not_used);
}
@@ -7330,21 +7968,24 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT(fixed == 1);
int err;
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0;
- if (value)
- return my_strntoll(value->charset(), value->ptr(),
- value->length(), 10, (char**) 0, &err);
- else
- return (longlong)0;
+ }
+ return my_strntoll(value->charset(), value->ptr(),
+ value->length(), 10, (char**) 0, &err);
}
String* Item_cache_str::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return 0;
+ }
return value;
}
@@ -7352,20 +7993,24 @@ String* Item_cache_str::val_str(String *str)
my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= TRUE;
return NULL;
- if (value)
- string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
- else
- decimal_val= 0;
+ }
+ string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
return decimal_val;
}
int Item_cache_str::save_in_field(Field *field, bool no_conversions)
{
- if (!value_cached && !cache_value())
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ field->set_notnull();
+ null_value= TRUE;
return 0;
+ }
int res= Item_cache::save_in_field(field, no_conversions);
return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
value->length() < field->field_length) ? 1 : res;
diff --git a/sql/item.h b/sql/item.h
index 3f732cf126e..2f536ba94ea 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -506,12 +506,16 @@ public:
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
- XPATH_NODESET, XPATH_NODESET_CMP};
+ XPATH_NODESET, XPATH_NODESET_CMP,
+ VIEW_FIXER_ITEM, EXPR_CACHE_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
enum traverse_order { POSTFIX, PREFIX };
+ /* Cache of the result of is_expensive(). */
+ int8 is_expensive_cache;
+
/* Reuse size, only used by SP local variable assignment, otherwize 0 */
uint rsize;
@@ -574,6 +578,12 @@ public:
Field *make_string_field(TABLE *table);
virtual bool fix_fields(THD *, Item **);
/*
+ Fix after some tables has been pulled out. Basically re-calculate all
+ attributes that are dependent on the tables.
+ */
+ virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref) {};
+
+ /*
This method should be used in case where we are sure that we do not need
complete fix_fields() procedure.
Usually this method is used by the optimizer when it has to create a new
@@ -736,6 +746,17 @@ public:
*/
virtual bool val_bool();
virtual String *val_nodeset(String*) { return 0; }
+
+ /*
+ save_val() is method of val_* family which stores value in the given
+ field.
+ */
+ virtual void save_val(Field *to) { save_org_in_field(to); }
+ /*
+ save_result() is method of val*result() family which stores value in
+ the given field.
+ */
+ virtual void save_result(Field *to) { save_val(to); }
/* Helper functions, see item_sum.cc */
String *val_string_from_real(String *str);
String *val_string_from_int(String *str);
@@ -928,6 +949,7 @@ public:
virtual bool remove_fixed(uchar * arg) { fixed= 0; return 0; }
virtual bool cleanup_processor(uchar *arg);
virtual bool collect_item_field_processor(uchar * arg) { return 0; }
+ virtual bool add_field_to_set_processor(uchar * arg) { return 0; }
virtual bool find_item_in_field_list_processor(uchar *arg) { return 0; }
virtual bool change_context_processor(uchar *context) { return 0; }
virtual bool reset_query_id_processor(uchar *query_id_arg) { return 0; }
@@ -1106,6 +1128,8 @@ public:
virtual Item *neg_transformer(THD *thd) { return NULL; }
virtual Item *update_value_transformer(uchar *select_arg) { return this; }
+ virtual Item *expr_cache_insert_transformer(uchar *thd_arg) { return this; }
+ virtual bool expr_cache_is_needed(THD *) { return FALSE; }
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
void delete_self()
{
@@ -1132,15 +1156,43 @@ public:
*/
virtual bool result_as_longlong() { return FALSE; }
bool is_datetime();
+
+ /*
+ Test whether an expression is expensive to compute. Used during
+ optimization to avoid computing expensive expressions during this
+ phase. Also used to force temp tables when sorting on expensive
+ functions.
+ TODO:
+ Normally we should have a method:
+ cost Item::execution_cost(),
+ where 'cost' is either 'double' or some structure of various cost
+ parameters.
+
+ NOTE
+ This function is now used to prevent evaluation of materialized IN
+ subquery predicates before it is allowed. grep for
+ DontEvaluateMaterializedSubqueryTooEarly to see the uses.
+ */
+ virtual bool is_expensive()
+ {
+ if (is_expensive_cache < 0)
+ is_expensive_cache= walk(&Item::is_expensive_processor, 0, (uchar*)0);
+ return test(is_expensive_cache);
+ }
virtual Field::geometry_type get_geometry_type() const
{ return Field::GEOM_GEOMETRY; };
String *check_well_formed_result(String *str, bool send_error= 0);
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
+
+ Item* set_expr_cache(THD *thd, List<Item*> &depends_on);
+ virtual Item *get_cached_item() { return NULL; }
};
/*
- Class to be used to enumerate all field references in an item tree.
+ Class to be used to enumerate all field references in an item tree. This
+ includes references to outside but not fields of the tables within a
+ subquery.
Suggested usage:
class My_enumerator : public Field_enumerator
@@ -1157,7 +1209,7 @@ public:
class Field_enumerator
{
public:
- virtual void visit_field(Field *field)= 0;
+ virtual void visit_field(Item_field *field)= 0;
virtual ~Field_enumerator() {}; /* purecov: inspected */
Field_enumerator() {} /* Remove gcc warning */
};
@@ -1513,6 +1565,19 @@ public:
*/
TABLE_LIST *cached_table;
st_select_lex *depended_from;
+ /*
+ Some Items resolved in another select should not be marked as dependency
+ of the subquery where they are. During normal name resolution, we check
+ this. Stored procedures and prepared statements first try to resolve an
+ ident item using a cached table reference and field position from the
+ previous query execution (cached_table/cached_field_index). If the
+ tables were not changed, the ident matches the table/field, and we have
+ faster resolution of the ident without looking through all tables and
+ fields in the query. But in this case, we can not check all conditions
+ about this ident item dependency, so we should cache the condition in
+ this variable.
+ */
+ bool can_be_depended;
Item_ident(Name_resolution_context *context_arg,
const char *db_name_arg, const char *table_name_arg,
const char *field_name_arg);
@@ -1595,6 +1660,7 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal *);
String *val_str(String*);
+ void save_result(Field *to);
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
@@ -1604,6 +1670,7 @@ public:
bool send(Protocol *protocol, String *str_arg);
void reset_field(Field *f);
bool fix_fields(THD *, Item **);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void make_field(Send_field *tmp_field);
int save_in_field(Field *field,bool no_conversions);
void save_org_in_field(Field *field);
@@ -1634,6 +1701,7 @@ public:
void update_null_value();
Item *get_tmp_table_item(THD *thd);
bool collect_item_field_processor(uchar * arg);
+ bool add_field_to_set_processor(uchar * arg);
bool find_item_in_field_list_processor(uchar *arg);
bool register_field_in_read_map(uchar *arg);
bool register_field_in_bitmap(uchar *arg);
@@ -1913,8 +1981,6 @@ public:
virtual void print(String *str, enum_query_type query_type);
Item_num *neg ();
uint decimal_precision() const { return max_length; }
- bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
- bool check_vcol_func_processor(uchar *arg) { return FALSE;}
};
@@ -2376,6 +2442,8 @@ public:
Item *it= ((Item *) item)->real_item();
return ref && (*ref)->eq(it, binary_cmp);
}
+ void save_val(Field *to);
+ void save_result(Field *to);
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
@@ -2392,6 +2460,7 @@ public:
bool send(Protocol *prot, String *tmp);
void make_field(Send_field *field);
bool fix_fields(THD *, Item **);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
int save_in_field(Field *field, bool no_conversions);
void save_org_in_field(Field *field);
enum Item_result result_type () const { return (*ref)->result_type(); }
@@ -2424,10 +2493,15 @@ public:
return ref ? (*ref)->real_item() : this;
}
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
- {
- return (*ref)->walk(processor, walk_subquery, arg) ||
- (this->*processor)(arg);
+ {
+ if (ref && *ref)
+ return (*ref)->walk(processor, walk_subquery, arg) ||
+ (this->*processor)(arg);
+ else
+ return FALSE;
}
+ bool enumerate_field_refs_processor(uchar *arg)
+ { return (*ref)->enumerate_field_refs_processor(arg); }
void no_rows_in_result()
{
(*ref)->no_rows_in_result();
@@ -2508,6 +2582,7 @@ public:
alias_name_used_arg)
{}
+ void save_val(Field *to);
double val_real();
longlong val_int();
String *val_str(String* tmp);
@@ -2518,6 +2593,131 @@ public:
virtual Ref_Type ref_type() { return DIRECT_REF; }
};
+class Expression_cache;
+class Item_cache;
+
+
+/**
+ The objects of this class can store its values in an expression cache.
+*/
+
+class Item_cache_wrapper :public Item_result_field
+{
+private:
+ /* Pointer on the cached expression */
+ Item *orig_item;
+ Expression_cache *expr_cache;
+ /*
+ In order to put the expression into the expression cache and return
+ value of val_*() method, we will need to get the expression value twice
+ (probably in different types). In order to avoid making two
+ (potentially costly) orig_item->val_*() calls, we store expression value
+ in this Item_cache object.
+ */
+ Item_cache *expr_value;
+
+ Item *check_cache();
+ inline void cache();
+
+public:
+ Item_cache_wrapper(Item *item_arg);
+ ~Item_cache_wrapper();
+
+ const char *func_name() const { return "<expr_cache>"; }
+ enum Type type() const { return EXPR_CACHE_ITEM; }
+ virtual Item *get_cached_item() { return orig_item; }
+
+ bool set_cache(THD *thd, List<Item*> &depends_on);
+
+ bool fix_fields(THD *thd, Item **it);
+ void fix_length_and_dec() {}
+ void cleanup();
+
+ /* Methods of getting value which should be cached in the cache */
+ void save_val(Field *to);
+ double val_real();
+ longlong val_int();
+ String *val_str(String* tmp);
+ my_decimal *val_decimal(my_decimal *);
+ bool val_bool();
+ bool is_null();
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
+ bool get_time(MYSQL_TIME *ltime);
+ bool send(Protocol *protocol, String *buffer)
+ {
+ if (result_field)
+ return protocol->store(result_field);
+ return Item::send(protocol, buffer);
+ }
+ void save_org_in_field(Field *field)
+ {
+ save_val(field);
+ }
+ void save_in_result_field(bool no_conversions)
+ {
+ save_val(result_field);
+ }
+ Item* get_tmp_table_item(THD *thd_arg);
+
+ /* Following methods make this item transparent as much as possible */
+
+ virtual void print(String *str, enum_query_type query_type);
+ virtual const char *full_name() const { return orig_item->full_name(); }
+ virtual void make_field(Send_field *field) { orig_item->make_field(field); }
+ bool eq(const Item *item, bool binary_cmp) const
+ {
+ Item *it= ((Item *) item)->real_item();
+ return orig_item->eq(it, binary_cmp);
+ }
+ void fix_after_pullout(st_select_lex *new_parent, Item **refptr)
+ {
+ orig_item->fix_after_pullout(new_parent, &orig_item);
+ }
+ int save_in_field(Field *to, bool no_conversions);
+ enum Item_result result_type () const { return orig_item->result_type(); }
+ enum_field_types field_type() const { return orig_item->field_type(); }
+ table_map used_tables() const { return orig_item->used_tables(); }
+ void update_used_tables() { orig_item->update_used_tables(); }
+ bool const_item() const { return orig_item->const_item(); }
+ table_map not_null_tables() const { return orig_item->not_null_tables(); }
+ bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
+ {
+ return orig_item->walk(processor, walk_subquery, arg) ||
+ (this->*processor)(arg);
+ }
+ bool enumerate_field_refs_processor(uchar *arg)
+ { return orig_item->enumerate_field_refs_processor(arg); }
+ bool result_as_longlong() { return orig_item->result_as_longlong(); }
+ Item_field *filed_for_view_update()
+ { return orig_item->filed_for_view_update(); }
+
+ /* Row emulation: forwarding of ROW-related calls to orig_item */
+ uint cols()
+ { return result_type() == ROW_RESULT ? orig_item->cols() : 1; }
+ Item* element_index(uint i)
+ { return result_type() == ROW_RESULT ? orig_item->element_index(i) : this; }
+ Item** addr(uint i)
+ { return result_type() == ROW_RESULT ? orig_item->addr(i) : 0; }
+ bool check_cols(uint c)
+ {
+ return (result_type() == ROW_RESULT ?
+ orig_item->check_cols(c) :
+ Item::check_cols(c));
+ }
+ bool null_inside()
+ { return result_type() == ROW_RESULT ? orig_item->null_inside() : 0; }
+ void bring_value()
+ {
+ if (result_type() == ROW_RESULT)
+ orig_item->bring_value();
+ }
+ bool check_vcol_func_processor(uchar *arg)
+ {
+ return trace_unsupported_by_check_vcol_func_processor("cache");
+ }
+};
+
+
/*
Class for view fields, the same as Item_direct_ref, but call fix_fields
of reference if it is not called yet
@@ -2595,6 +2795,7 @@ public:
outer_ref->save_org_in_field(result_field);
}
bool fix_fields(THD *, Item **);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
table_map used_tables() const
{
return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
@@ -2627,6 +2828,7 @@ public:
const char *table_name_arg, const char *field_name_arg)
:Item_ref(context_arg, item, table_name_arg, field_name_arg),
owner(master) {}
+ void save_val(Field *to);
double val_real();
longlong val_int();
String* val_str(String* s);
@@ -2889,6 +3091,17 @@ public:
};
+/*
+ Cached_item_XXX objects are not exactly caches. They do the following:
+
+ Each Cached_item_XXX object has
+ - its source item
+ - saved value of the source item
+ - cmp() method that compares the saved value with the current value of the
+ source item, and if they were not equal saves item's value into the saved
+ value.
+*/
+
class Cached_item :public Sql_alloc
{
public:
@@ -2945,9 +3158,10 @@ class Cached_item_field :public Cached_item
uint length;
public:
- Cached_item_field(Item_field *item)
+ Cached_item_field(Field *arg_field) : field(arg_field)
{
- field= item->field;
+ field= arg_field;
+ /* TODO: take the memory allocation below out of the constructor. */
buff= (uchar*) sql_calloc(length=field->pack_length());
}
bool cmp(void);
@@ -3151,7 +3365,8 @@ public:
example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING),
value_cached(0)
{
- fixed= 1;
+ fixed= 1;
+ maybe_null= 1;
null_value= 1;
}
Item_cache(enum_field_types field_type_arg):
@@ -3159,6 +3374,7 @@ public:
value_cached(0)
{
fixed= 1;
+ maybe_null= 1;
null_value= 1;
}
@@ -3392,7 +3608,8 @@ void mark_select_range_as_dependent(THD *thd,
Field *found_field, Item *found_item,
Item_ident *resolved_item);
-extern Cached_item *new_Cached_item(THD *thd, Item *item);
+extern Cached_item *new_Cached_item(THD *thd, Item *item,
+ bool pass_through_ref);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item);
extern int stored_field_cmp_to_item(THD *thd, Field *field, Item *item);
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 0ac4edb3656..b15083f54a2 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -27,11 +27,15 @@
Create right type of Cached_item for an item.
*/
-Cached_item *new_Cached_item(THD *thd, Item *item)
+Cached_item *new_Cached_item(THD *thd, Item *item, bool pass_through_ref)
{
- if (item->real_item()->type() == Item::FIELD_ITEM &&
+ if (pass_through_ref && item->real_item()->type() == Item::FIELD_ITEM &&
!(((Item_field *) (item->real_item()))->field->flags & BLOB_FLAG))
- return new Cached_item_field((Item_field *) (item->real_item()));
+ {
+ Item_field *real_item= (Item_field *) item->real_item();
+ Field *cached_field= real_item->field;
+ return new Cached_item_field(cached_field);
+ }
switch (item->result_type()) {
case STRING_RESULT:
return new Cached_item_str(thd, (Item_field *) item);
@@ -117,14 +121,20 @@ bool Cached_item_int::cmp(void)
bool Cached_item_field::cmp(void)
{
- bool tmp= field->cmp(buff) != 0; // This is not a blob!
- if (tmp)
- field->get_image(buff,length,field->charset());
+ bool tmp= FALSE; // Value is identical
+ /* Note that field can't be a blob here ! */
if (null_value != field->is_null())
{
null_value= !null_value;
- tmp=TRUE;
+ tmp= TRUE; // Value has changed
}
+
+ /*
+ If value is not null and value changed (from null to not null or
+ becasue of value change), then copy the new value to buffer.
+ */
+ if (! null_value && (tmp || (tmp= (field->cmp(buff) != 0))))
+ field->get_image(buff,length,field->charset());
return tmp;
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index d7fa6cba030..0b89adb75e8 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1772,6 +1772,52 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
/**
+ Add an expression cache for this subquery if it is needed
+
+ @param thd_arg Thread handle
+
+ @details
+ The function checks whether an expression cache is needed for this item
+ and if if so wraps the item into an item of the class
+ Item_exp_cache_wrapper with an appropriate expression cache set up there.
+
+ @note
+ used from Item::transform()
+
+ @return
+ new wrapper item if an expression cache is needed,
+ this item - otherwise
+*/
+
+Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
+{
+ THD *thd= (THD*) thd_arg;
+ DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
+ List<Item*> &depends_on= ((Item_subselect *)args[1])->depends_on;
+
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
+ /* Add left expression to the list of the parameters of the subquery */
+ if (args[0]->cols() == 1)
+ depends_on.push_front((Item**)args);
+ else
+ {
+ for (uint i= 0; i < args[0]->cols(); i++)
+ {
+ depends_on.push_front(args[0]->addr(i));
+ }
+ }
+
+ if (args[1]->expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd, depends_on)))
+ DBUG_RETURN(expr_cache);
+
+ depends_on.pop();
+ DBUG_RETURN(this);
+}
+
+/*
The implementation of optimized \<outer expression\> [NOT] IN \<subquery\>
predicates. The implementation works as follows.
@@ -1841,6 +1887,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
@see Item_in_subselect::val_bool()
@see Item_is_not_null_test::val_int()
*/
+
longlong Item_in_optimizer::val_int()
{
bool tmp;
@@ -1942,6 +1989,7 @@ void Item_in_optimizer::cleanup()
Item_bool_func::cleanup();
if (!save_cache)
cache= 0;
+ expr_cache= 0;
DBUG_VOID_RETURN;
}
@@ -1953,6 +2001,70 @@ bool Item_in_optimizer::is_null()
}
+/**
+ Transform an Item_in_optimizer and its arguments with a callback function.
+
+ @param transformer the transformer callback function to be applied to the
+ nodes of the tree of the object
+ @param parameter to be passed to the transformer
+
+ @detail
+ Recursively transform the left and the right operand of this Item. The
+ Right operand is an Item_in_subselect or its subclass. To avoid the
+ creation of new Items, we use the fact the the left operand of the
+ Item_in_subselect is the same as the one of 'this', so instead of
+ transforming its operand, we just assign the left operand of the
+ Item_in_subselect to be equal to the left operand of 'this'.
+ The transformation is not applied further to the subquery operand
+ if the IN predicate.
+
+ @returns
+ @retval pointer to the transformed item
+ @retval NULL if an error occurred
+*/
+
+Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
+{
+ Item *new_item;
+
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+ DBUG_ASSERT(arg_count == 2);
+
+ /* Transform the left IN operand. */
+ new_item= (*args)->transform(transformer, argument);
+ if (!new_item)
+ return 0;
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
+ if ((*args) != new_item)
+ current_thd->change_item_tree(args, new_item);
+
+ /*
+ Transform the right IN operand which should be an Item_in_subselect or a
+ subclass of it. The left operand of the IN must be the same as the left
+ operand of this Item_in_optimizer, so in this case there is no further
+ transformation, we only make both operands the same.
+ TODO: is it the way it should be?
+ */
+ DBUG_ASSERT((args[1])->type() == Item::SUBSELECT_ITEM &&
+ (((Item_subselect*)(args[1]))->substype() ==
+ Item_subselect::IN_SUBS ||
+ ((Item_subselect*)(args[1]))->substype() ==
+ Item_subselect::ALL_SUBS ||
+ ((Item_subselect*)(args[1]))->substype() ==
+ Item_subselect::ANY_SUBS));
+
+ Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
+ in_arg->left_expr= args[0];
+
+ return (this->*transformer)(argument);
+}
+
+
longlong Item_func_eq::val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -4201,11 +4313,15 @@ Item_cond::fix_fields(THD *thd, Item **ref)
DBUG_ASSERT(fixed == 0);
List_iterator<Item> li(list);
Item *item;
+ TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
#ifndef EMBEDDED_LIBRARY
uchar buff[sizeof(char*)]; // Max local vars in function
#endif
not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 1;
+
+ if (functype() != COND_AND_FUNC)
+ thd->thd_marker.emb_on_expr_nest= NULL;
/*
and_table_cache is the value that Item_cond_or() returns for
not_null_tables()
@@ -4264,11 +4380,45 @@ 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;
}
+
+void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ List_iterator<Item> li(list);
+ Item *item;
+
+ used_tables_cache=0;
+ const_item_cache=1;
+
+ and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
+ not_null_tables_cache= 0;
+
+ while ((item=li++))
+ {
+ table_map tmp_table_map;
+ item->fix_after_pullout(new_parent, li.ref());
+ item= *li.ref();
+ used_tables_cache|= item->used_tables();
+ const_item_cache&= item->const_item();
+
+ if (item->const_item())
+ and_tables_cache= (table_map) 0;
+ else
+ {
+ tmp_table_map= item->not_null_tables();
+ not_null_tables_cache|= tmp_table_map;
+ and_tables_cache&= tmp_table_map;
+ const_item_cache= FALSE;
+ }
+ }
+}
+
+
bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
{
List_iterator_fast<Item> li(list);
@@ -5617,7 +5767,7 @@ longlong Item_equal::val_int()
void Item_equal::fix_length_and_dec()
{
- Item *item= get_first();
+ Item *item= get_first(NULL);
eval_item= cmp_item::get_comparator(item->result_type(),
item->collation.collation);
}
@@ -5680,3 +5830,130 @@ void Item_equal::print(String *str, enum_query_type query_type)
str->append(')');
}
+
+/*
+ @brief Get the first equal field of multiple equality.
+ @param[in] field the field to get equal field to
+
+ @details Get the first field of multiple equality that is equal to the
+ given field. In order to make semi-join materialization strategy work
+ correctly we can't propagate equal fields from upper select to a
+ materialized semi-join.
+ Thus the fields is returned according to following rules:
+
+ 1) If the given field belongs to a semi-join then the first field in
+ multiple equality which belong to the same semi-join is returned.
+ Otherwise NULL is returned.
+ 2) If the given field doesn't belong to a semi-join then
+ the first field in the multiple equality that doesn't belong to any
+ semi-join is returned.
+ If all fields in the equality are belong to semi-join(s) then NULL
+ is returned.
+ 3) If no field is given then the first field in the multiple equality
+ is returned without regarding whether it belongs to a semi-join or not.
+
+ @retval Found first field in the multiple equality.
+ @retval 0 if no field found.
+*/
+
+Item_field* Item_equal::get_first(Item_field *field)
+{
+ List_iterator<Item_field> it(fields);
+ Item_field *item;
+ JOIN_TAB *field_tab;
+ if (!field)
+ return fields.head();
+
+ /*
+ Of all equal fields, return the first one we can use. Normally, this is the
+ field which belongs to the table that is the first in the join order.
+
+ There is one exception to this: When semi-join materialization strategy is
+ used, and the given field belongs to a table within the semi-join nest, we
+ must pick the first field in the semi-join nest.
+
+ Example: suppose we have a join order:
+
+ ot1 ot2 SJ-Mat(it1 it2 it3) ot3
+
+ and equality ot2.col = it1.col = it2.col
+ If we're looking for best substitute for 'it2.col', we should pick it1.col
+ and not ot2.col.
+
+ eliminate_item_equal() also has code that deals with equality substitution
+ in presense of SJM nests.
+ */
+
+ field_tab= field->field->table->reginfo.join_tab;
+
+ TABLE_LIST *emb_nest= field->field->table->pos_in_table_list->embedding;
+
+ if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used)
+ {
+ /*
+ It's a field from an materialized semi-join. We can substitute it only
+ for a field from the same semi-join.
+ */
+ JOIN_TAB *first= field_tab;
+ JOIN *join= field_tab->join;
+ int tab_idx= field_tab - field_tab->join->join_tab;
+
+ DBUG_ASSERT(join->join_tab[tab_idx].table->map &
+ emb_nest->sj_inner_tables);
+
+ /* Find the first table of this semi-join nest */
+ for (int i= tab_idx-1; i >= (int)join->const_tables; i--)
+ {
+ if (join->join_tab[i].table->map & emb_nest->sj_inner_tables)
+ first= join->join_tab + i;
+ else
+ // Found first tab that doesn't belong to current SJ.
+ break;
+ }
+ /* Find an item to substitute for. */
+ while ((item= it++))
+ {
+ if (item->field->table->reginfo.join_tab >= first)
+ {
+ /*
+ If we found given field then return NULL to avoid unnecessary
+ substitution.
+ */
+ return (item != field) ? item : NULL;
+ }
+ }
+ }
+ else
+ {
+#if 0
+ /*
+ The field is not in SJ-Materialization nest. We must return the first
+ field that's not embedded in a SJ-Materialization nest.
+ Example: suppose we have a join order:
+
+ SJ-Mat(it1 it2) ot1 ot2
+
+ and equality ot2.col = ot1.col = it2.col
+ If we're looking for best substitute for 'ot2.col', we should pick ot1.col
+ and not it2.col, because when we run a join between ot1 and ot2
+ execution of SJ-Mat(...) has already finished and we can't rely on the
+ value of it*.*.
+ psergey-fix-fix: ^^ THAT IS INCORRECT ^^. Pick the first, whatever that
+ is.
+ */
+ while ((item= it++))
+ {
+ TABLE_LIST *emb_nest= item->field->table->pos_in_table_list->embedding;
+ if (!emb_nest || !emb_nest->sj_mat_info ||
+ !emb_nest->sj_mat_info->is_used)
+ {
+ return item;
+ }
+ }
+#endif
+ return fields.head();
+ }
+ // Shouldn't get here.
+ DBUG_ASSERT(0);
+ return NULL;
+}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index c45d6bef315..8a62f69de1f 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -242,6 +242,7 @@ class Item_in_optimizer: public Item_bool_func
{
protected:
Item_cache *cache;
+ Item *expr_cache;
bool save_cache;
/*
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
@@ -252,7 +253,7 @@ protected:
int result_for_null_param;
public:
Item_in_optimizer(Item *a, Item_in_subselect *b):
- Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
+ Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), expr_cache(0),
save_cache(0), result_for_null_param(UNKNOWN)
{}
bool fix_fields(THD *, Item **);
@@ -263,6 +264,8 @@ public:
const char *func_name() const { return "<in_optimizer>"; }
Item_cache **get_cache() { return &cache; }
void keep_top_level_cache();
+ Item *transform(Item_transformer transformer, uchar *arg);
+ virtual Item *expr_cache_insert_transformer(uchar *thd_arg);
};
class Comp_creator
@@ -370,6 +373,7 @@ public:
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
uint decimal_precision() const { return 1; }
void top_level_item() { abort_on_null= TRUE; }
+ Arg_comparator *get_comparator() { return &cmp; }
void cleanup()
{
Item_int_func::cleanup();
@@ -486,13 +490,23 @@ public:
class Item_func_eq :public Item_bool_rowready_func2
{
public:
- Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
+ Item_func_eq(Item *a,Item *b) :
+ Item_bool_rowready_func2(a,b), in_equality_no(UINT_MAX)
+ {}
longlong val_int();
enum Functype functype() const { return EQ_FUNC; }
enum Functype rev_functype() const { return EQ_FUNC; }
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "="; }
Item *negated_item();
+ /*
+ - If this equality is created from the subquery's IN-equality:
+ number of the item it was created from, e.g. for
+ (a,b) IN (SELECT c,d ...) a=c will have in_equality_no=0,
+ and b=d will have in_equality_no=1.
+ - Otherwise, UINT_MAX
+ */
+ uint in_equality_no;
};
class Item_func_equal :public Item_bool_rowready_func2
@@ -1500,6 +1514,7 @@ public:
list.prepand(nlist);
}
bool fix_fields(THD *, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
enum Type type() const { return COND_ITEM; }
List<Item>* argument_list() { return &list; }
@@ -1619,7 +1634,7 @@ public:
void add(Item_field *f);
uint members();
bool contains(Field *field);
- Item_field* get_first() { return fields.head(); }
+ Item_field* get_first(Item_field *field);
uint n_fields() { return fields.elements; }
void merge(Item_equal *item);
void update_const();
@@ -1637,6 +1652,9 @@ public:
virtual void print(String *str, enum_query_type query_type);
CHARSET_INFO *compare_collation()
{ return fields.head()->collation.collation; }
+ friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
+ Item_equal *item_equal);
+ friend bool setup_sj_materialization(struct st_join_table *tab);
};
class COND_EQUAL: public Sql_alloc
@@ -1743,14 +1761,34 @@ inline bool is_cond_or(Item *item)
class Item_cond_xor :public Item_cond
{
public:
- Item_cond_xor() :Item_cond() {}
- Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
+ Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2)
+ {
+ /*
+ Items must be stored in args[] as well because this Item_cond is
+ treated as a FUNC_ITEM (see type()). I.e., users of it will get
+ it's children by calling arguments(), not argument_list(). This
+ is a temporary solution until XOR is optimized and treated like
+ a full Item_cond citizen.
+ */
+ arg_count= 2;
+ args= tmp_arg;
+ args[0]= i1;
+ args[1]= i2;
+ }
enum Functype functype() const { return COND_XOR_FUNC; }
/* TODO: remove the next line when implementing XOR optimization */
enum Type type() const { return FUNC_ITEM; }
longlong val_int();
const char *func_name() const { return "xor"; }
void top_level_item() {}
+ /* Since child Items are stored in args[], Items cannot be added.
+ However, since Item_cond_xor is treated as a FUNC_ITEM (see
+ type()), the methods below should never be called.
+ */
+ bool add(Item *item) { DBUG_ASSERT(FALSE); return FALSE; }
+ bool add_at_head(Item *item) { DBUG_ASSERT(FALSE); return FALSE; }
+ bool add_at_head(List<Item> *nlist) { DBUG_ASSERT(FALSE); return FALSE; }
+ void copy_andor_arguments(THD *thd, Item_cond *item) { DBUG_ASSERT(FALSE); }
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1db8f6e8da6..dfad8a9af06 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -150,9 +150,11 @@ Item_func::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
Item **arg,**arg_end;
+ TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
#endif
+ thd->thd_marker.emb_on_expr_nest= NULL;
used_tables_cache= not_null_tables_cache= 0;
const_item_cache=1;
@@ -199,6 +201,7 @@ 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;
}
@@ -218,6 +221,28 @@ Item_func::quick_fix_field()
}
+void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ Item **arg,**arg_end;
+
+ used_tables_cache= not_null_tables_cache= 0;
+ const_item_cache=1;
+
+ if (arg_count)
+ {
+ for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
+ {
+ (*arg)->fix_after_pullout(new_parent, arg);
+ Item *item= *arg;
+
+ used_tables_cache|= item->used_tables();
+ not_null_tables_cache|= item->not_null_tables();
+ const_item_cache&= item->const_item();
+ }
+ }
+}
+
+
bool Item_func::walk(Item_processor processor, bool walk_subquery,
uchar *argument)
{
@@ -479,12 +504,12 @@ Field *Item_func::tmp_table_field(TABLE *table)
return field;
}
-
+/*
bool Item_func::is_expensive_processor(uchar *arg)
{
return is_expensive();
}
-
+*/
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
{
@@ -2955,7 +2980,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
String *res= arguments[i]->val_str(&buffers[i]);
if (arguments[i]->null_value)
continue;
- f_args.args[i]= (char*) res->c_ptr();
+ f_args.args[i]= (char*) res->c_ptr_safe();
f_args.lengths[i]= res->length();
break;
}
@@ -5790,7 +5815,7 @@ Item_func_sp::cleanup()
sp_result_field= NULL;
}
m_sp= NULL;
- dummy_table->alias= NULL;
+ dummy_table->alias.free();
Item_func::cleanup();
}
@@ -5816,7 +5841,7 @@ Item_func_sp::func_name() const
qname.append('.');
}
append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length);
- return qname.ptr();
+ return qname.c_ptr_safe();
}
@@ -5872,7 +5897,7 @@ Item_func_sp::init_result_field(THD *thd)
*/
share= dummy_table->s;
- dummy_table->alias = "";
+ dummy_table->alias.set("", 0, table_alias_charset);
dummy_table->maybe_null = maybe_null;
dummy_table->in_use= thd;
dummy_table->copy_blobs= TRUE;
diff --git a/sql/item_func.h b/sql/item_func.h
index 99660bd2a40..9c0d827d582 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -117,6 +117,7 @@ public:
// Constructor used for Item_cond_and/or (see Item comment)
Item_func(THD *thd, Item_func *item);
bool fix_fields(THD *, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void quick_fix_field();
table_map used_tables() const;
table_map not_null_tables() const;
@@ -181,8 +182,8 @@ public:
Item_transformer transformer, uchar *arg_t);
void traverse_cond(Cond_traverser traverser,
void * arg, traverse_order order);
- bool is_expensive_processor(uchar *arg);
- virtual bool is_expensive() { return 0; }
+ // bool is_expensive_processor(uchar *arg);
+ // virtual bool is_expensive() { return 0; }
inline double fix_result(double value)
{
if (isfinite(value))
@@ -1085,6 +1086,7 @@ class Item_udf_func :public Item_func
{
protected:
udf_handler udf;
+ bool is_expensive_processor(uchar *arg) { return TRUE; }
public:
Item_udf_func(udf_func *udf_arg)
@@ -1708,6 +1710,9 @@ private:
bool execute();
bool execute_impl(THD *thd);
bool init_result_field(THD *thd);
+
+protected:
+ bool is_expensive_processor(uchar *arg) { return TRUE; }
public:
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 7535c1fa80b..b8fbba2c90e 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -131,6 +131,20 @@ void Item_row::update_used_tables()
}
}
+
+void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ used_tables_cache= 0;
+ const_item_cache= 1;
+ 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();
+ }
+}
+
+
bool Item_row::check_cols(uint c)
{
if (c != arg_count)
diff --git a/sql/item_row.h b/sql/item_row.h
index 3566ff079c6..c7fb8d59220 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -60,6 +60,7 @@ public:
return 0;
};
bool fix_fields(THD *thd, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void cleanup();
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
table_map used_tables() const { return used_tables_cache; };
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 6d3a4c66649..ff318fa5d73 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -31,21 +31,18 @@
#include "mysql_priv.h"
#include "sql_select.h"
-inline Item * and_items(Item* cond, Item *item)
-{
- return (cond? (new Item_cond_and(cond, item)) : item);
-}
Item_subselect::Item_subselect():
Item_result_field(), value_assigned(0), thd(0), substitution(0),
- engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
- const_item_cache(1), in_fix_fields(0), eliminated(FALSE),
- engine_changed(0), changed(0), is_correlated(FALSE)
+ expr_cache(0), engine(0), old_engine(0), used_tables_cache(0),
+ have_to_be_excluded(0), const_item_cache(1), inside_first_fix_fields(0),
+ done_first_fix_fields(FALSE), eliminated(FALSE), engine_changed(0),
+ changed(0), is_correlated(FALSE)
{
with_subselect= 1;
reset();
/*
- item value is NULL if select_subselect not changed this value
+ Item value is NULL if select_result_interceptor didn't change this value
(i.e. some rows will be found returned)
*/
null_value= TRUE;
@@ -53,7 +50,7 @@ Item_subselect::Item_subselect():
void Item_subselect::init(st_select_lex *select_lex,
- select_subselect *result)
+ select_result_interceptor *result)
{
/*
Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
@@ -63,6 +60,7 @@ void Item_subselect::init(st_select_lex *select_lex,
DBUG_ENTER("Item_subselect::init");
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
unit= select_lex->master_unit();
+ thd= unit->thd;
if (unit->item)
{
@@ -79,6 +77,7 @@ void Item_subselect::init(st_select_lex *select_lex,
else
{
SELECT_LEX *outer_select= unit->outer_select();
+ DBUG_ASSERT(thd);
/*
do not take into account expression inside aggregate functions because
they can access original table fields
@@ -87,14 +86,16 @@ void Item_subselect::init(st_select_lex *select_lex,
NO_MATTER :
outer_select->parsing_place);
if (unit->is_union())
- engine= new subselect_union_engine(unit, result, this);
+ engine= new subselect_union_engine(thd, unit, result, this);
else
- engine= new subselect_single_select_engine(select_lex, result, this);
+ engine= new subselect_single_select_engine(thd, select_lex, result, this);
}
{
SELECT_LEX *upper= unit->outer_select();
if (upper->parsing_place == IN_HAVING)
upper->subquery_in_having= 1;
+ /* The subquery is an expression cache candidate */
+ upper->expr_cache_may_be_used[upper->parsing_place]= TRUE;
}
DBUG_VOID_RETURN;
}
@@ -118,8 +119,10 @@ void Item_subselect::cleanup()
}
if (engine)
engine->cleanup();
+ depends_on.empty();
reset();
value_assigned= 0;
+ expr_cache= 0;
DBUG_VOID_RETURN;
}
@@ -146,6 +149,22 @@ void Item_singlerow_subselect::cleanup()
DBUG_VOID_RETURN;
}
+
+void Item_in_subselect::cleanup()
+{
+ DBUG_ENTER("Item_in_subselect::cleanup");
+ if (left_expr_cache)
+ {
+ left_expr_cache->delete_elements();
+ delete left_expr_cache;
+ left_expr_cache= NULL;
+ }
+ first_execution= TRUE;
+ is_constant= FALSE;
+ Item_subselect::cleanup();
+ DBUG_VOID_RETURN;
+}
+
Item_subselect::~Item_subselect()
{
delete engine;
@@ -166,21 +185,42 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
bool res;
DBUG_ASSERT(fixed == 0);
- engine->set_thd((thd= thd_param));
- if (!in_fix_fields)
- refers_to.empty();
+ /* There is no reason to get a different THD. */
+ DBUG_ASSERT(thd == thd_param);
+ if (!done_first_fix_fields)
+ {
+ done_first_fix_fields= TRUE;
+ inside_first_fix_fields= TRUE;
+ upper_refs.empty();
+ /*
+ psergey-todo: remove _first_fix_fields calls, we need changes on every
+ execution
+ */
+ }
+
eliminated= FALSE;
+ parent_select= thd_param->lex->current_select;
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
return TRUE;
- in_fix_fields++;
if (!(res= engine->prepare()))
{
// all transformation is done (used by prepared statements)
changed= 1;
+ inside_first_fix_fields= FALSE;
+
+ // all transformation is done (used by prepared statements)
+ changed= 1;
+
+ /*
+ Substitute the current item with an Item_in_optimizer that was
+ created by Item_in_subselect::select_in_like_transformer and
+ call fix_fields for the substituted item which in turn calls
+ engine->prepare for the subquery predicate.
+ */
if (substitution)
{
// did we changed top item of WHERE condition
@@ -198,12 +238,13 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (!(*ref)->fixed)
res= (*ref)->fix_fields(thd, ref);
goto end;
+//psergey-merge: done_first_fix_fields= FALSE;
}
// Is it one field subselect?
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
- res= 1;
+//psergey-merge: done_first_fix_fields= FALSE;
goto end;
}
fix_length_and_dec();
@@ -220,7 +261,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
fixed= 1;
end:
- in_fix_fields--;
+ done_first_fix_fields= FALSE;
thd->where= save_where;
return res;
}
@@ -228,11 +269,12 @@ end:
bool Item_subselect::enumerate_field_refs_processor(uchar *arg)
{
- List_iterator<Item> it(refers_to);
- Item *item;
- while ((item= it++))
+ List_iterator<Ref_to_outside> it(upper_refs);
+ Ref_to_outside *upper;
+
+ while ((upper= it++))
{
- if (item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
+ if (upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
return TRUE;
}
return FALSE;
@@ -244,6 +286,144 @@ bool Item_subselect::mark_as_eliminated_processor(uchar *arg)
return FALSE;
}
+
+bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
+ Item *item)
+{
+ if (inside_first_fix_fields)
+ {
+ is_correlated= TRUE;
+ Ref_to_outside *upper;
+ if (!(upper= new (thd->stmt_arena->mem_root) Ref_to_outside()))
+ return TRUE;
+ upper->select= select;
+ upper->item= item;
+ if (upper_refs.push_back(upper, thd->stmt_arena->mem_root))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Adjust attributes after our parent select has been merged into grandparent
+
+ DESCRIPTION
+ Subquery is a composite object which may be correlated, that is, it may
+ have
+ 1. references to tables of the parent select (i.e. one that has the clause
+ with the subquery predicate)
+ 2. references to tables of the grandparent select
+ 3. references to tables of further ancestors.
+
+ Before the pullout, this item indicates:
+ - #1 with table bits in used_tables()
+ - #2 and #3 with OUTER_REF_TABLE_BIT.
+
+ After parent has been merged with grandparent:
+ - references to parent and grandparent tables should be indicated with
+ table bits.
+ - references to greatgrandparent and further ancestors - with
+ OUTER_REF_TABLE_BIT.
+*/
+
+void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ recalc_used_tables(new_parent, TRUE);
+ parent_select= new_parent;
+}
+
+
+class Field_fixer: public Field_enumerator
+{
+public:
+ table_map used_tables; /* Collect used_tables here */
+ st_select_lex *new_parent; /* Select we're in */
+ virtual void visit_field(Item_field *item)
+ {
+ //for (TABLE_LIST *tbl= new_parent->leaf_tables; tbl; tbl= tbl->next_local)
+ //{
+ // if (tbl->table == field->table)
+ // {
+ used_tables|= item->field->table->map;
+ // return;
+ // }
+ //}
+ //used_tables |= OUTER_REF_TABLE_BIT;
+ }
+};
+
+
+/*
+ Recalculate used_tables_cache
+*/
+
+void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
+ bool after_pullout)
+{
+ List_iterator<Ref_to_outside> it(upper_refs);
+ Ref_to_outside *upper;
+
+ used_tables_cache= 0;
+ while ((upper= it++))
+ {
+ bool found= FALSE;
+ /*
+ Check if
+ 1. the upper reference refers to the new immediate parent select, or
+ 2. one of the further ancestors.
+
+ We rely on the fact that the tree of selects is modified by some kind of
+ 'flattening', i.e. a process where child selects are merged into their
+ parents.
+ The merged selects are removed from the select tree but keep pointers to
+ their parents.
+ */
+ for (st_select_lex *sel= upper->select; sel; sel= sel->outer_select())
+ {
+ /*
+ If we've reached the new parent select by walking upwards from
+ reference's original select, this means that the reference is now
+ referring to the direct parent:
+ */
+ if (sel == new_parent)
+ {
+ found= TRUE;
+ /*
+ upper->item may be NULL when we've referred to a grouping function,
+ in which case we don't care about what it's table_map really is,
+ because item->with_sum_func==1 will ensure correct placement of the
+ item.
+ */
+ if (upper->item)
+ {
+ // Now, iterate over fields and collect used_tables() attribute:
+ Field_fixer fixer;
+ fixer.used_tables= 0;
+ fixer.new_parent= new_parent;
+ upper->item->walk(&Item::enumerate_field_refs_processor, FALSE,
+ (uchar*)&fixer);
+ used_tables_cache |= fixer.used_tables;
+ /*
+ if (after_pullout)
+ upper->item->fix_after_pullout(new_parent, &(upper->item));
+ upper->item->update_used_tables();
+ used_tables_cache |= upper->item->used_tables();
+ */
+ }
+ }
+ }
+ if (!found)
+ used_tables_cache|= OUTER_REF_TABLE_BIT;
+ }
+ /*
+ Don't update const_tables_cache yet as we don't yet know which of the
+ parent's tables are constant. Parent will call update_used_tables() after
+ he has done const table detection, and that will be our chance to update
+ const_tables_cache.
+ */
+}
+
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
uchar *argument)
{
@@ -311,6 +491,97 @@ bool Item_subselect::exec()
return (res);
}
+
+/**
+ Check if an expression cache is needed for this subquery
+
+ @param thd Thread handle
+
+ @details
+ The function checks whether a cache is needed for a subquery and whether
+ the result of the subquery can be put in cache.
+
+ @retval TRUE cache is needed
+ @retval FALSE otherwise
+*/
+
+bool Item_subselect::expr_cache_is_needed(THD *thd)
+{
+ return (depends_on.elements &&
+ engine->cols() == 1 &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
+ !(engine->uncacheable() & (UNCACHEABLE_RAND |
+ UNCACHEABLE_SIDEEFFECT)));
+}
+
+
+/**
+ Check if an expression cache is needed for this subquery
+
+ @param thd Thread handle
+
+ @details
+ The function checks whether a cache is needed for a subquery and whether
+ the result of the subquery can be put in cache.
+
+ @note
+ This method allows many columns in the subquery because it is supported by
+ Item_in optimizer and result of the IN subquery will be scalar in this
+ case.
+
+ @retval TRUE cache is needed
+ @retval FALSE otherwise
+*/
+
+bool Item_in_subselect::expr_cache_is_needed(THD *thd)
+{
+ return (depends_on.elements &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
+ !(engine->uncacheable() & (UNCACHEABLE_RAND |
+ UNCACHEABLE_SIDEEFFECT)));
+}
+
+
+/*
+ Compute the IN predicate if the left operand's cache changed.
+*/
+
+bool Item_in_subselect::exec()
+{
+ DBUG_ENTER("Item_in_subselect::exec");
+ /*
+ Initialize the cache of the left predicate operand. This has to be done as
+ late as now, because Cached_item directly contains a resolved field (not
+ an item, and in some cases (when temp tables are created), these fields
+ end up pointing to the wrong field. One solution is to change Cached_item
+ to not resolve its field upon creation, but to resolve it dynamically
+ from a given Item_ref object.
+ TODO: the cache should be applied conditionally based on:
+ - rules - e.g. only if the left operand is known to be ordered, and/or
+ - 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 && exec_method == MATERIALIZATION)
+ init_left_expr_cache();
+
+ /*
+ If the new left operand is already in the cache, reuse the old result.
+ Use the cached result only if this is not the first execution of IN
+ because the cache is not valid for the first execution.
+ */
+ if (!first_execution && left_expr_cache &&
+ test_if_item_cache_changed(*left_expr_cache) < 0)
+ DBUG_RETURN(FALSE);
+
+ /*
+ The exec() method below updates item::value, and item::null_value, thus if
+ we don't call it, the next call to item::val_int() will return whatever
+ result was computed by its previous call.
+ */
+ DBUG_RETURN(Item_subselect::exec());
+}
+
+
Item::Type Item_subselect::type() const
{
return SUBSELECT_ITEM;
@@ -343,6 +614,7 @@ Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
void Item_subselect::update_used_tables()
{
+ recalc_used_tables(parent_select, FALSE);
if (!engine->uncacheable())
{
// did all used tables become static?
@@ -471,8 +743,9 @@ void Item_singlerow_subselect::reset()
Item_subselect::trans_res
Item_singlerow_subselect::select_transformer(JOIN *join)
{
+ DBUG_ENTER("Item_singlerow_subselect::select_transformer");
if (changed)
- return RES_OK;
+ DBUG_RETURN(RES_OK);
SELECT_LEX *select_lex= join->select_lex;
Query_arena *arena= thd->stmt_arena;
@@ -515,15 +788,18 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
*/
substitution->walk(&Item::remove_dependence_processor, 0,
(uchar *) select_lex->outer_select());
- return RES_REDUCE;
+ DBUG_RETURN(RES_REDUCE);
}
- return RES_OK;
+ DBUG_RETURN(RES_OK);
}
void Item_singlerow_subselect::store(uint i, Item *item)
{
row[i]->store(item);
+ //psergey-merge: can do without that: row[i]->cache_value();
+ //psergey-backport-timours: ^ really, without that ^
+ //psergey-try-merge-again:
row[i]->cache_value();
}
@@ -564,6 +840,40 @@ void Item_singlerow_subselect::fix_length_and_dec()
maybe_null= engine->may_be_null();
}
+
+/**
+ Add an expression cache for this subquery if it is needed
+
+ @param thd_arg Thread handle
+
+ @details
+ The function checks whether an expression cache is needed for this item
+ and if if so wraps the item into an item of the class
+ Item_exp_cache_wrapper with an appropriate expression cache set up there.
+
+ @note
+ used from Item::transform()
+
+ @return
+ new wrapper item if an expression cache is needed,
+ this item - otherwise
+*/
+
+Item* Item_singlerow_subselect::expr_cache_insert_transformer(uchar *thd_arg)
+{
+ THD *thd= (THD*) thd_arg;
+ DBUG_ENTER("Item_singlerow_subselect::expr_cache_insert_transformer");
+
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
+ if (expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd, depends_on)))
+ DBUG_RETURN(expr_cache);
+ DBUG_RETURN(this);
+}
+
+
uint Item_singlerow_subselect::cols()
{
return engine->cols();
@@ -710,8 +1020,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(), optimizer(0), transformed(0),
- pushed_cond_guards(NULL), upper_item(0)
+ Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
+ is_constant(FALSE), optimizer(0), pushed_cond_guards(NULL),
+ exec_method(NOT_TRANSFORMED), upper_item(0)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp;
@@ -725,13 +1036,18 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
DBUG_VOID_RETURN;
}
+int Item_in_subselect::get_identifier()
+{
+ return engine->get_identifier();
+}
+
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
chooser_compare_func_creator fc,
st_select_lex *select_lex,
bool all_arg)
:Item_in_subselect(), func_creator(fc), all(all_arg)
{
- DBUG_ENTER("Item_in_subselect::Item_in_subselect");
+ DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
left_expr= left_exp;
func= func_creator(all_arg);
init(select_lex, new select_exists_subselect(this));
@@ -753,6 +1069,40 @@ void Item_exists_subselect::fix_length_and_dec()
unit->global_parameters->select_limit= new Item_int((int32) 1);
}
+
+/**
+ Add an expression cache for this subquery if it is needed
+
+ @param thd_arg Thread handle
+
+ @details
+ The function checks whether an expression cache is needed for this item
+ and if if so wraps the item into an item of the class
+ Item_exp_cache_wrapper with an appropriate expression cache set up there.
+
+ @note
+ used from Item::transform()
+
+ @return
+ new wrapper item if an expression cache is needed,
+ this item - otherwise
+*/
+
+Item* Item_exists_subselect::expr_cache_insert_transformer(uchar *thd_arg)
+{
+ THD *thd= (THD*) thd_arg;
+ DBUG_ENTER("Item_exists_subselect::expr_cache_insert_transformer");
+
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
+ if (substype() == EXISTS_SUBS && expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd, depends_on)))
+ DBUG_RETURN(expr_cache);
+ DBUG_RETURN(this);
+}
+
+
double Item_exists_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
@@ -902,6 +1252,8 @@ bool Item_in_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
null_value= was_null= FALSE;
+ if (is_constant)
+ return value;
if (exec())
{
reset();
@@ -977,10 +1329,10 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
HAVING trigcond(<is_not_null_test>(ie))
RETURN
- RES_OK - OK, either subquery was transformed, or appopriate
- predicates where injected into it.
- RES_REDUCE - The subquery was reduced to non-subquery
- RES_ERROR - Error
+ RES_OK Either subquery was transformed, or appopriate
+ predicates where injected into it.
+ RES_REDUCE The subquery was reduced to non-subquery
+ RES_ERROR Error
*/
Item_subselect::trans_res
@@ -994,6 +1346,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
Check that the right part of the subselect contains no more than one
column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
*/
+ // psergey: duplicated_subselect_card_check
if (select_lex->item_list.elements > 1)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
@@ -1099,6 +1452,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
thd->lex->current_select= current;
+ /* We will refer to upper level cache array => we have to save it for SP */
+ optimizer->keep_top_level_cache();
+
/*
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
we can use same item for all selects.
@@ -1109,7 +1465,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
(char *)in_left_expr_name);
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
+ //psergey: placed then removed: select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
}
+
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
{
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
@@ -1117,6 +1475,60 @@ Item_in_subselect::single_value_transformer(JOIN *join,
pushed_cond_guards[0]= TRUE;
}
+ /*
+ If this IN predicate can be computed via materialization, do not
+ perform the IN -> EXISTS transformation.
+ */
+ if (exec_method == MATERIALIZATION)
+ DBUG_RETURN(RES_OK);
+
+ /* Perform the IN=>EXISTS transformation. */
+ DBUG_RETURN(single_value_in_to_exists_transformer(join, func));
+}
+
+
+/**
+ Transofrm an IN predicate into EXISTS via predicate injection.
+
+ @details The transformation injects additional predicates into the subquery
+ (and makes the subquery correlated) as follows.
+
+ - If the subquery has aggregates, GROUP BY, or HAVING, convert to
+
+ SELECT ie FROM ... HAVING subq_having AND
+ trigcond(oe $cmp$ ref_or_null_helper<ie>)
+
+ the addition is wrapped into trigger only when we want to distinguish
+ between NULL and FALSE results.
+
+ - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
+ following:
+
+ = If we don't need to distinguish between NULL and FALSE subquery:
+
+ SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
+
+ = If we need to distinguish between those:
+
+ SELECT 1 FROM ...
+ WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
+ HAVING trigcond(<is_not_null_test>(ie))
+
+ @param join Join object of the subquery (i.e. 'child' join).
+ @param func Subquery comparison creator
+
+ @retval RES_OK Either subquery was transformed, or appopriate
+ predicates where injected into it.
+ @retval RES_REDUCE The subquery was reduced to non-subquery
+ @retval RES_ERROR Error
+*/
+
+Item_subselect::trans_res
+Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
+{
+ SELECT_LEX *select_lex= join->select_lex;
+ DBUG_ENTER("Item_in_subselect::single_value_in_to_exists_transformer");
+
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
if (join->having || select_lex->with_sum_func ||
select_lex->group_list.elements)
@@ -1296,19 +1708,21 @@ Item_subselect::trans_res
Item_in_subselect::row_value_transformer(JOIN *join)
{
SELECT_LEX *select_lex= join->select_lex;
- Item *having_item= 0;
uint cols_num= left_expr->cols();
- bool is_having_used= (join->having || select_lex->with_sum_func ||
- select_lex->group_list.first ||
- !select_lex->table_list.elements);
+
DBUG_ENTER("Item_in_subselect::row_value_transformer");
- if (select_lex->item_list.elements != left_expr->cols())
+ // psergey: duplicated_subselect_card_check
+ if (select_lex->item_list.elements != cols_num)
{
- my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
+ my_error(ER_OPERAND_COLUMNS, MYF(0), cols_num);
DBUG_RETURN(RES_ERROR);
}
+ /*
+ Wrap the current IN predicate in an Item_in_optimizer. The actual
+ substitution in the Item tree takes place in Item_subselect::fix_fields.
+ */
if (!substitution)
{
//first call for this unit
@@ -1340,6 +1754,48 @@ Item_in_subselect::row_value_transformer(JOIN *join)
}
}
+ /*
+ If this IN predicate can be computed via materialization, do not
+ perform the IN -> EXISTS transformation.
+ */
+ if (exec_method == MATERIALIZATION)
+ DBUG_RETURN(RES_OK);
+
+ /* Perform the IN=>EXISTS transformation. */
+ DBUG_RETURN(row_value_in_to_exists_transformer(join));
+}
+
+
+/**
+ Tranform a (possibly non-correlated) IN subquery into a correlated EXISTS.
+
+ @todo
+ The IF-ELSE below can be refactored so that there is no duplication of the
+ statements that create the new conditions. For this we have to invert the IF
+ and the FOR statements as this:
+ for (each left operand)
+ create the equi-join condition
+ if (is_having_used || !abort_on_null)
+ create the "is null" and is_not_null_test items
+ if (is_having_used)
+ add the equi-join and the null tests to HAVING
+ else
+ add the equi-join and the "is null" to WHERE
+ add the is_not_null_test to HAVING
+*/
+
+Item_subselect::trans_res
+Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
+{
+ SELECT_LEX *select_lex= join->select_lex;
+ Item *having_item= 0;
+ uint cols_num= left_expr->cols();
+ bool is_having_used= (join->having || select_lex->with_sum_func ||
+ select_lex->group_list.first ||
+ !select_lex->table_list.elements);
+
+ DBUG_ENTER("Item_in_subselect::row_value_in_to_exists_transformer");
+
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
if (is_having_used)
{
@@ -1360,7 +1816,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
for (uint i= 0; i < cols_num; i++)
{
DBUG_ASSERT((left_expr->fixed &&
- select_lex->ref_pointer_array[i]->fixed) ||
+ select_lex->ref_pointer_array[i]->fixed) ||
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
Item_ref::OUTER_REF));
@@ -1438,7 +1894,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
{
Item *item, *item_isnull;
DBUG_ASSERT((left_expr->fixed &&
- select_lex->ref_pointer_array[i]->fixed) ||
+ select_lex->ref_pointer_array[i]->fixed) ||
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
Item_ref::OUTER_REF));
@@ -1583,9 +2039,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
}
if (changed)
- {
DBUG_RETURN(RES_OK);
- }
thd->where= "IN/ALL/ANY subquery";
@@ -1593,6 +2047,8 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
In some optimisation cases we will not need this Item_in_optimizer
object, but we can't know it here, but here we need address correct
reference on left expresion.
+
+ //psergey: he means degenerate cases like "... IN (SELECT 1)"
*/
if (!optimizer)
{
@@ -1614,7 +2070,12 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
if (result)
goto err;
- transformed= 1;
+ /*
+ If we didn't choose an execution method up to this point, we choose
+ the IN=>EXISTS transformation.
+ */
+ if (exec_method == NOT_TRANSFORMED)
+ exec_method= IN_TO_EXISTS;
arena= thd->activate_stmt_arena_if_needed(&backup);
/*
@@ -1648,7 +2109,7 @@ err:
void Item_in_subselect::print(String *str, enum_query_type query_type)
{
- if (transformed)
+ if (exec_method == IN_TO_EXISTS)
str->append(STRING_WITH_LEN("<exists>"));
else
{
@@ -1661,28 +2122,250 @@ void Item_in_subselect::print(String *str, enum_query_type query_type)
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
{
- bool result = 0;
-
- if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed)
- result = left_expr->fix_fields(thd_arg, &left_expr);
+ uint outer_cols_num;
+ List<Item> *inner_cols;
+
+ if (exec_method == SEMI_JOIN)
+ return !( (*ref)= new Item_int(1));
+
+ /*
+ Check if the outer and inner IN operands match in those cases when we
+ will not perform IN=>EXISTS transformation. Currently this is when we
+ use subquery materialization.
+
+ The condition below is true when this method was called recursively from
+ inside JOIN::prepare for the JOIN object created by the call chain
+ Item_subselect::fix_fields -> subselect_single_select_engine::prepare,
+ which creates a JOIN object for the subquery and calls JOIN::prepare for
+ the JOIN of the subquery.
+ Notice that in some cases, this doesn't happen, and the check_cols()
+ test for each Item happens later in
+ Item_in_subselect::row_value_in_to_exists_transformer.
+ The reason for this mess is that our JOIN::prepare phase works top-down
+ instead of bottom-up, so we first do name resoluton and semantic checks
+ for the outer selects, then for the inner.
+ */
+ if (engine &&
+ engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE &&
+ ((subselect_single_select_engine*)engine)->join)
+ {
+ outer_cols_num= left_expr->cols();
- return result || Item_subselect::fix_fields(thd_arg, ref);
+ if (unit->is_union())
+ inner_cols= &(unit->types);
+ else
+ inner_cols= &(unit->first_select()->item_list);
+ if (outer_cols_num != inner_cols->elements)
+ {
+ my_error(ER_OPERAND_COLUMNS, MYF(0), outer_cols_num);
+ return TRUE;
+ }
+ if (outer_cols_num > 1)
+ {
+ List_iterator<Item> inner_col_it(*inner_cols);
+ Item *inner_col;
+ for (uint i= 0; i < outer_cols_num; i++)
+ {
+ inner_col= inner_col_it++;
+ if (inner_col->check_cols(left_expr->element_index(i)->cols()))
+ return TRUE;
+ }
+ }
+ }
+
+ if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed &&
+ left_expr->fix_fields(thd_arg, &left_expr))
+ return TRUE;
+ if (Item_subselect::fix_fields(thd_arg, ref))
+ return TRUE;
+
+ fixed= TRUE;
+
+ return FALSE;
+}
+
+
+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);
+}
+
+void Item_in_subselect::update_used_tables()
+{
+ Item_subselect::update_used_tables();
+ left_expr->update_used_tables();
+ used_tables_cache |= left_expr->used_tables();
+}
+
+/**
+ Try to create an engine to compute the subselect via materialization,
+ and if this fails, revert to execution via the IN=>EXISTS transformation.
+
+ @details
+ The purpose of this method is to hide the implementation details
+ of this Item's execution. The method creates a new engine for
+ materialized execution, and initializes the engine.
+
+ If this initialization fails
+ - either because it wasn't possible to create the needed temporary table
+ and its index,
+ - or because of a memory allocation error,
+ then we revert back to execution via the IN=>EXISTS tranformation.
+
+ The initialization of the new engine is divided in two parts - a permanent
+ one that lives across prepared statements, and one that is repeated for each
+ execution.
+
+ @returns
+ @retval TRUE memory allocation error occurred
+ @retval FALSE an execution method was chosen successfully
+*/
+
+bool Item_in_subselect::setup_engine()
+{
+ subselect_hash_sj_engine *new_engine= NULL;
+ bool res= FALSE;
+
+ DBUG_ENTER("Item_in_subselect::setup_engine");
+
+ if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
+ {
+ /* Create/initialize objects in permanent memory. */
+ subselect_single_select_engine *old_engine;
+ Query_arena *arena= thd->stmt_arena, backup;
+
+ old_engine= (subselect_single_select_engine*) engine;
+
+ if (arena->is_conventional())
+ arena= 0;
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+
+ if (!(new_engine= new subselect_hash_sj_engine(thd, this,
+ old_engine)) ||
+ new_engine->init_permanent(unit->get_unit_column_types()))
+ {
+ Item_subselect::trans_res trans_res;
+ /*
+ If for some reason we cannot use materialization for this IN predicate,
+ delete all materialization-related objects, and apply the IN=>EXISTS
+ transformation.
+ */
+ delete new_engine;
+ new_engine= NULL;
+ exec_method= NOT_TRANSFORMED;
+ if (left_expr->cols() == 1)
+ trans_res= single_value_in_to_exists_transformer(old_engine->join,
+ &eq_creator);
+ else
+ trans_res= row_value_in_to_exists_transformer(old_engine->join);
+ res= (trans_res != Item_subselect::RES_OK);
+ }
+ if (new_engine)
+ engine= new_engine;
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ }
+ else
+ {
+ DBUG_ASSERT(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
+ new_engine= (subselect_hash_sj_engine*) engine;
+ }
+
+ /* Initilizations done in runtime memory, repeated for each execution. */
+ if (new_engine)
+ {
+ /*
+ Reset the LIMIT 1 set in Item_exists_subselect::fix_length_and_dec.
+ TODO:
+ Currently we set the subquery LIMIT to infinity, and this is correct
+ because we forbid at parse time LIMIT inside IN subqueries (see
+ Item_in_subselect::test_limit). However, once we allow this, here
+ we should set the correct limit if given in the query.
+ */
+ unit->global_parameters->select_limit= NULL;
+ if ((res= new_engine->init_runtime()))
+ DBUG_RETURN(res);
+ }
+
+ DBUG_RETURN(res);
+}
+
+
+/**
+ Initialize the cache of the left operand of the IN predicate.
+
+ @note This method has the same purpose as alloc_group_fields(),
+ but it takes a different kind of collection of items, and the
+ list we push to is dynamically allocated.
+
+ @retval TRUE if a memory allocation error occurred or the cache is
+ not applicable to the current query
+ @retval FALSE if success
+*/
+
+bool Item_in_subselect::init_left_expr_cache()
+{
+ JOIN *outer_join;
+
+ outer_join= unit->outer_select()->join;
+ /*
+ An IN predicate might be evaluated in a query for which all tables have
+ been optimzied away.
+ */
+ if (!outer_join || !outer_join->tables || !outer_join->tables_list)
+ return TRUE;
+
+ if (!(left_expr_cache= new List<Cached_item>))
+ return TRUE;
+
+ for (uint i= 0; i < left_expr->cols(); i++)
+ {
+ Cached_item *cur_item_cache= new_Cached_item(thd,
+ left_expr->element_index(i),
+ FALSE);
+ if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Callback to test if an IN predicate is expensive.
+
+ @details
+ IN predicates are considered expensive only if they will be executed via
+ materialization. The return value affects the behavior of
+ make_cond_for_table() in such a way that it is unchanged when we use
+ the IN=>EXISTS transformation to compute IN.
+
+ @retval TRUE if the predicate is expensive
+ @retval FALSE otherwise
+*/
+
+bool Item_in_subselect::is_expensive_processor(uchar *arg)
+{
+ return exec_method == MATERIALIZATION;
}
Item_subselect::trans_res
Item_allany_subselect::select_transformer(JOIN *join)
{
- transformed= 1;
+ DBUG_ENTER("Item_allany_subselect::select_transformer");
+ exec_method= IN_TO_EXISTS;
if (upper_item)
upper_item->show= 1;
- return select_in_like_transformer(join, func);
+ DBUG_RETURN(select_in_like_transformer(join, func));
}
void Item_allany_subselect::print(String *str, enum_query_type query_type)
{
- if (transformed)
+ if (exec_method == IN_TO_EXISTS)
str->append(STRING_WITH_LEN("<exists>"));
else
{
@@ -1704,21 +2387,24 @@ void subselect_engine::set_thd(THD *thd_arg)
subselect_single_select_engine::
-subselect_single_select_engine(st_select_lex *select,
- select_subselect *result_arg,
+subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
+ select_result_interceptor *result_arg,
Item_subselect *item_arg)
- :subselect_engine(item_arg, result_arg),
- prepared(0), optimized(0), executed(0),
- select_lex(select), join(0)
+ :subselect_engine(thd_arg, item_arg, result_arg),
+ prepared(0), executed(0), select_lex(select), join(0)
{
select_lex->master_unit()->item= item_arg;
}
+int subselect_single_select_engine::get_identifier()
+{
+ return select_lex->select_number;
+}
void subselect_single_select_engine::cleanup()
{
DBUG_ENTER("subselect_single_select_engine::cleanup");
- prepared= optimized= executed= 0;
+ prepared= executed= 0;
join= 0;
result->cleanup();
DBUG_VOID_RETURN;
@@ -1761,21 +2447,21 @@ bool subselect_union_engine::no_rows()
return test(!unit->fake_select_lex->join->send_records);
}
+
void subselect_uniquesubquery_engine::cleanup()
{
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
- /*
- subselect_uniquesubquery_engine have not 'result' assigbed, so we do not
- cleanup() it
- */
+ /* Tell handler we don't need the index anymore */
+ if (tab->table->file->inited)
+ tab->table->file->ha_index_end();
DBUG_VOID_RETURN;
}
-subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
- select_subselect *result_arg,
+subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
+ select_result_interceptor *result_arg,
Item_subselect *item_arg)
- :subselect_engine(item_arg, result_arg)
+ :subselect_engine(thd_arg, item_arg, result_arg)
{
unit= u;
if (!result_arg) //out of memory
@@ -1784,6 +2470,32 @@ subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
}
+/**
+ Create and prepare the JOIN object that represents the query execution
+ plan for the subquery.
+
+ @details
+ This method is called from Item_subselect::fix_fields. For prepared
+ statements it is called both during the PREPARE and EXECUTE phases in the
+ following ways:
+ - During PREPARE the optimizer needs some properties
+ (join->fields_list.elements) of the JOIN to proceed with preparation of
+ the remaining query (namely to complete ::fix_fields for the subselect
+ related classes. In the end of PREPARE the JOIN is deleted.
+ - When we EXECUTE the query, Item_subselect::fix_fields is called again, and
+ the JOIN object is re-created again, prepared and executed. In the end of
+ execution it is deleted.
+ In all cases the JOIN is created in runtime memory (not in the permanent
+ memory root).
+
+ @todo
+ Re-check what properties of 'join' are needed during prepare, and see if
+ we can avoid creating a JOIN during JOIN::prepare of the outer join.
+
+ @retval 0 if success
+ @retval 1 if error
+*/
+
int subselect_single_select_engine::prepare()
{
if (prepared)
@@ -1825,8 +2537,8 @@ int subselect_union_engine::prepare()
int subselect_uniquesubquery_engine::prepare()
{
- //this never should be called
- DBUG_ASSERT(0);
+ /* Should never be called. */
+ DBUG_ASSERT(FALSE);
return 1;
}
@@ -1873,7 +2585,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
if (!(row[i]= Item_cache::get_cache(sel_item)))
return;
row[i]->setup(sel_item);
- row[i]->store(sel_item);
+ //psergey-backport-timours: row[i]->store(sel_item);
}
if (item_list.elements > 1)
res_type= ROW_RESULT;
@@ -1921,11 +2633,10 @@ int subselect_single_select_engine::exec()
char const *save_where= thd->where;
SELECT_LEX *save_select= thd->lex->current_select;
thd->lex->current_select= select_lex;
- if (!optimized)
+ if (!join->optimized)
{
SELECT_LEX_UNIT *unit= select_lex->master_unit();
- optimized= 1;
unit->set_limit(unit->global_parameters);
if (join->optimize())
{
@@ -2080,14 +2791,23 @@ int subselect_uniquesubquery_engine::scan_table()
for (;;)
{
error=table->file->ha_rnd_next(table->record[0]);
- if (error && error != HA_ERR_END_OF_FILE)
- {
- error= report_error(table, error);
- break;
+ if (error) {
+ if (error == HA_ERR_RECORD_DELETED)
+ {
+ error= 0;
+ continue;
+ }
+ if (error == HA_ERR_END_OF_FILE)
+ {
+ error= 0;
+ break;
+ }
+ else
+ {
+ error= report_error(table, error);
+ break;
+ }
}
- /* No more rows */
- if (table->status)
- break;
if (!cond || cond->val_int())
{
@@ -2198,6 +2918,56 @@ bool subselect_uniquesubquery_engine::copy_ref_key()
/*
+ @retval 1 A NULL was found in the outer reference, index lookup is
+ not applicable, the outer ref is unsusable as a lookup key,
+ use some other method to find a match.
+ @retval 0 The outer ref was copied into an index lookup key.
+ @retval -1 The outer ref cannot possibly match any row, IN is FALSE.
+*/
+/* TIMOUR: this method is a variant of copy_ref_key(), needs refactoring. */
+
+int subselect_uniquesubquery_engine::copy_ref_key_simple()
+{
+ for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
+ {
+ enum store_key::store_key_result store_res;
+ store_res= (*copy)->copy();
+ tab->ref.key_err= store_res;
+
+ /*
+ When there is a NULL part in the key we don't need to make index
+ lookup for such key thus we don't need to copy whole key.
+ If we later should do a sequential scan return OK. Fail otherwise.
+
+ See also the comment for the subselect_uniquesubquery_engine::exec()
+ function.
+ */
+ null_keypart= (*copy)->null_key;
+ if (null_keypart)
+ return 1;
+
+ /*
+ Check if the error is equal to STORE_KEY_FATAL. This is not expressed
+ using the store_key::store_key_result enum because ref.key_err is a
+ boolean and we want to detect both TRUE and STORE_KEY_FATAL from the
+ space of the union of the values of [TRUE, FALSE] and
+ store_key::store_key_result.
+ TODO: fix the variable an return types.
+ */
+ if (store_res == store_key::STORE_KEY_FATAL)
+ {
+ /*
+ Error converting the left IN operand to the column type of the right
+ IN operand.
+ */
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+/*
Execute subselect
SYNOPSIS
@@ -2237,7 +3007,13 @@ int subselect_uniquesubquery_engine::exec()
/* TODO: change to use of 'full_scan' here? */
if (copy_ref_key())
+ {
+ /*
+ TIMOUR: copy_ref_key() == 1 means NULL result, not error, why return 1?
+ Check who reiles on this result.
+ */
DBUG_RETURN(1);
+ }
if (table->status)
{
/*
@@ -2278,10 +3054,51 @@ int subselect_uniquesubquery_engine::exec()
}
+/*
+ TIMOUR: write comment
+*/
+
+int subselect_uniquesubquery_engine::index_lookup()
+{
+ DBUG_ENTER("subselect_uniquesubquery_engine::index_lookup");
+ int error;
+ TABLE *table= tab->table;
+
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key, 0);
+ error= table->file->ha_index_read_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->
+ ref.key_parts),
+ HA_READ_KEY_EXACT);
+ DBUG_PRINT("info", ("lookup result: %i", error));
+
+ if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
+ {
+ /*
+ TIMOUR: I don't understand at all when do we need to call report_error.
+ In most places where we access an index, we don't do this. Why here?
+ */
+ error= report_error(table, error);
+ DBUG_RETURN(error);
+ }
+
+ table->null_row= 0;
+ if (!error && (!cond || cond->val_int()))
+ ((Item_in_subselect *) item)->value= 1;
+ else
+ ((Item_in_subselect *) item)->value= 0;
+
+ DBUG_RETURN(0);
+}
+
+
+
subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
{
/* Tell handler we don't need the index anymore */
- tab->table->file->ha_index_end();
+ //psergey-merge-todo: the following was gone in 6.0:
+ //psergey-merge: don't need this after all: tab->table->file->ha_index_end();
}
@@ -2289,7 +3106,7 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
Index-lookup subselect 'engine' - run the subquery
SYNOPSIS
- subselect_uniquesubquery_engine:exec()
+ subselect_indexsubquery_engine:exec()
full_scan
DESCRIPTION
@@ -2427,8 +3244,10 @@ int subselect_indexsubquery_engine::exec()
uint subselect_single_select_engine::cols()
{
- DBUG_ASSERT(select_lex->join != 0); // should be called after fix_fields()
- return select_lex->join->fields_list.elements;
+ //psergey-sj-backport: the following assert was gone in 6.0:
+ //DBUG_ASSERT(select_lex->join != 0); // should be called after fix_fields()
+ //return select_lex->join->fields_list.elements;
+ return select_lex->item_list.elements;
}
@@ -2510,10 +3329,20 @@ void subselect_union_engine::print(String *str, enum_query_type query_type)
void subselect_uniquesubquery_engine::print(String *str,
enum_query_type query_type)
{
+ char *table_name= tab->table->s->table_name.str;
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
tab->ref.items[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" in "));
- str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
+ if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
+ {
+ /*
+ Temporary tables' names change across runs, so they can't be used for
+ EXPLAIN EXTENDED.
+ */
+ str->append(STRING_WITH_LEN("<temporary table>"));
+ }
+ else
+ str->append(table_name, tab->table->s->table_name.length);
KEY *key_info= tab->table->key_info+ tab->ref.key;
str->append(STRING_WITH_LEN(" on "));
str->append(key_info->name);
@@ -2525,6 +3354,29 @@ void subselect_uniquesubquery_engine::print(String *str,
str->append(')');
}
+/*
+TODO:
+The above ::print method should be changed as below. Do it after
+all other tests pass.
+
+void subselect_uniquesubquery_engine::print(String *str)
+{
+ KEY *key_info= tab->table->key_info + tab->ref.key;
+ str->append(STRING_WITH_LEN("<primary_index_lookup>("));
+ for (uint i= 0; i < key_info->key_parts; i++)
+ tab->ref.items[i]->print(str);
+ str->append(STRING_WITH_LEN(" in "));
+ str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
+ str->append(STRING_WITH_LEN(" on "));
+ str->append(key_info->name);
+ if (cond)
+ {
+ str->append(STRING_WITH_LEN(" where "));
+ cond->print(str);
+ }
+ str->append(')');
+}
+*/
void subselect_indexsubquery_engine::print(String *str,
enum_query_type query_type)
@@ -2564,7 +3416,7 @@ void subselect_indexsubquery_engine::print(String *str,
*/
bool subselect_single_select_engine::change_result(Item_subselect *si,
- select_subselect *res)
+ select_result_interceptor *res)
{
item= si;
result= res;
@@ -2585,7 +3437,7 @@ bool subselect_single_select_engine::change_result(Item_subselect *si,
*/
bool subselect_union_engine::change_result(Item_subselect *si,
- select_subselect *res)
+ select_result_interceptor *res)
{
item= si;
int rc= unit->change_result(res, result);
@@ -2607,7 +3459,7 @@ bool subselect_union_engine::change_result(Item_subselect *si,
*/
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
- select_subselect *res)
+ select_result_interceptor *res)
{
DBUG_ASSERT(0);
return TRUE;
@@ -2675,5 +3527,1722 @@ bool subselect_union_engine::no_tables()
bool subselect_uniquesubquery_engine::no_tables()
{
/* returning value is correct, but this method should never be called */
+ DBUG_ASSERT(FALSE);
+ return 0;
+}
+
+
+/******************************************************************************
+ WL#1110 - Implementation of class subselect_hash_sj_engine
+******************************************************************************/
+
+
+/**
+ Check if an IN predicate should be executed via partial matching using
+ only schema information.
+
+ @details
+ This test essentially has three results:
+ - partial matching is applicable, but cannot be executed due to a
+ limitation in the total number of indexes, as a result we can't
+ use subquery materialization at all.
+ - partial matching is either applicable or not, and this can be
+ determined by looking at 'this->max_keys'.
+ If max_keys > 1, then we need partial matching because there are
+ more indexes than just the one we use during materialization to
+ remove duplicates.
+
+ @note
+ TIMOUR: The schema-based analysis for partial matching can be done once for
+ prepared statement and remembered. It is done here to remove the need to
+ save/restore all related variables between each re-execution, thus making
+ the code simpler.
+
+ @retval PARTIAL_MATCH if a partial match should be used
+ @retval COMPLETE_MATCH if a complete match (index lookup) should be used
+*/
+
+subselect_hash_sj_engine::exec_strategy
+subselect_hash_sj_engine::get_strategy_using_schema()
+{
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+
+ if (item_in->is_top_level_item())
+ return COMPLETE_MATCH;
+ else
+ {
+ List_iterator<Item> inner_col_it(*item_in->unit->get_unit_column_types());
+ Item *outer_col, *inner_col;
+
+ for (uint i= 0; i < item_in->left_expr->cols(); i++)
+ {
+ outer_col= item_in->left_expr->element_index(i);
+ inner_col= inner_col_it++;
+
+ if (!inner_col->maybe_null && !outer_col->maybe_null)
+ bitmap_set_bit(&non_null_key_parts, i);
+ else
+ {
+ bitmap_set_bit(&partial_match_key_parts, i);
+ ++count_partial_match_columns;
+ }
+ }
+ }
+
+ /* If no column contains NULLs use regular hash index lookups. */
+ if (count_partial_match_columns)
+ return PARTIAL_MATCH;
+ return COMPLETE_MATCH;
+}
+
+
+/**
+ Test whether an IN predicate must be computed via partial matching
+ based on the NULL statistics for each column of a materialized subquery.
+
+ @details The procedure analyzes column NULL statistics, updates the
+ matching type of columns that cannot be NULL or that contain only NULLs.
+ Based on this, the procedure determines the final execution strategy for
+ the [NOT] IN predicate.
+
+ @retval PARTIAL_MATCH if a partial match should be used
+ @retval COMPLETE_MATCH if a complete match (index lookup) should be used
+*/
+
+subselect_hash_sj_engine::exec_strategy
+subselect_hash_sj_engine::get_strategy_using_data()
+{
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+ select_materialize_with_stats *result_sink=
+ (select_materialize_with_stats *) result;
+ Item *outer_col;
+
+ /*
+ If we already determined that a complete match is enough based on schema
+ information, nothing can be better.
+ */
+ if (strategy == COMPLETE_MATCH)
+ return COMPLETE_MATCH;
+
+ for (uint i= 0; i < item_in->left_expr->cols(); i++)
+ {
+ if (!bitmap_is_set(&partial_match_key_parts, i))
+ continue;
+ outer_col= item_in->left_expr->element_index(i);
+ /*
+ If column 'i' doesn't contain NULLs, and the corresponding outer reference
+ cannot have a NULL value, then 'i' is a non-nullable column.
+ */
+ if (result_sink->get_null_count_of_col(i) == 0 && !outer_col->maybe_null)
+ {
+ bitmap_clear_bit(&partial_match_key_parts, i);
+ bitmap_set_bit(&non_null_key_parts, i);
+ --count_partial_match_columns;
+ }
+ if (result_sink->get_null_count_of_col(i) ==
+ tmp_table->file->stats.records)
+ ++count_null_only_columns;
+ }
+
+ /* If no column contains NULLs use regular hash index lookups. */
+ if (!count_partial_match_columns)
+ return COMPLETE_MATCH;
+ return PARTIAL_MATCH;
+}
+
+
+void
+subselect_hash_sj_engine::choose_partial_match_strategy(
+ bool has_non_null_key, bool has_covering_null_row,
+ MY_BITMAP *partial_match_key_parts)
+{
+ ulonglong pm_buff_size;
+
+ DBUG_ASSERT(strategy == PARTIAL_MATCH);
+ /*
+ Choose according to global optimizer switch. If only one of the switches is
+ 'ON', then the remaining strategy is the only possible one. The only cases
+ when this will be overriden is when the total size of all buffers for the
+ merge strategy is bigger than the 'rowid_merge_buff_size' system variable,
+ or if there isn't enough physical memory to allocate the buffers.
+ */
+ if (!optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN))
+ strategy= PARTIAL_MATCH_SCAN;
+ else if
+ ( optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) &&
+ !optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN))
+ strategy= PARTIAL_MATCH_MERGE;
+
+ /*
+ If both switches are ON, or both are OFF, we interpret that as "let the
+ optimizer decide". Perform a cost based choice between the two partial
+ matching strategies.
+ */
+ /*
+ TIMOUR: the above interpretation of the switch values could be changed to:
+ - if both are ON - let the optimizer decide,
+ - if both are OFF - do not use partial matching, therefore do not use
+ materialization in non-top-level predicates.
+ The problem with this is that we know for sure if we need partial matching
+ only after the subquery is materialized, and this is too late to revert to
+ the IN=>EXISTS strategy.
+ */
+ if (strategy == PARTIAL_MATCH)
+ {
+ /*
+ TIMOUR: Currently we use a super simplistic measure. This will be
+ addressed in a separate task.
+ */
+ if (tmp_table->file->stats.records < 100)
+ strategy= PARTIAL_MATCH_SCAN;
+ else
+ strategy= PARTIAL_MATCH_MERGE;
+ }
+
+ /* Check if there is enough memory for the rowid merge strategy. */
+ if (strategy == PARTIAL_MATCH_MERGE)
+ {
+ pm_buff_size= rowid_merge_buff_size(has_non_null_key,
+ has_covering_null_row,
+ partial_match_key_parts);
+ if (pm_buff_size > thd->variables.rowid_merge_buff_size)
+ strategy= PARTIAL_MATCH_SCAN;
+ }
+}
+
+
+/*
+ Compute the memory size of all buffers proportional to the number of rows
+ in tmp_table.
+
+ @details
+ If the result is bigger than thd->variables.rowid_merge_buff_size, partial
+ matching via merging is not applicable.
+*/
+
+ulonglong subselect_hash_sj_engine::rowid_merge_buff_size(
+ bool has_non_null_key, bool has_covering_null_row,
+ MY_BITMAP *partial_match_key_parts)
+{
+ /* Total size of all buffers used by partial matching. */
+ ulonglong buff_size;
+ ha_rows row_count= tmp_table->file->stats.records;
+ uint rowid_length= tmp_table->file->ref_length;
+ select_materialize_with_stats *result_sink=
+ (select_materialize_with_stats *) result;
+
+ /* Size of the subselect_rowid_merge_engine::row_num_to_rowid buffer. */
+ buff_size= row_count * rowid_length * sizeof(uchar);
+
+ if (has_non_null_key)
+ {
+ /* Add the size of Ordered_key::key_buff of the only non-NULL key. */
+ buff_size+= row_count * sizeof(rownum_t);
+ }
+
+ if (!has_covering_null_row)
+ {
+ for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
+ {
+ if (!bitmap_is_set(partial_match_key_parts, i) ||
+ result_sink->get_null_count_of_col(i) == row_count)
+ continue; /* In these cases we wouldn't construct Ordered keys. */
+
+ /* Add the size of Ordered_key::key_buff */
+ buff_size+= (row_count - result_sink->get_null_count_of_col(i)) *
+ sizeof(rownum_t);
+ /* Add the size of Ordered_key::null_key */
+ buff_size+= bitmap_buffer_size(result_sink->get_max_null_of_col(i));
+ }
+ }
+
+ return buff_size;
+}
+
+
+/*
+ Initialize a MY_BITMAP with a buffer allocated on the current
+ memory root.
+ TIMOUR: move to bitmap C file?
+*/
+
+static my_bool
+bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
+{
+ my_bitmap_map *bitmap_buf;
+
+ if (!(bitmap_buf= (my_bitmap_map*) alloc_root(mem_root,
+ bitmap_buffer_size(n_bits))) ||
+ bitmap_init(map, bitmap_buf, n_bits, FALSE))
+ return TRUE;
+ bitmap_clear_all(map);
+ return FALSE;
+}
+
+
+/**
+ Create all structures needed for IN execution that can live between PS
+ reexecution.
+
+ @param tmp_columns the items that produce the data for the temp table
+
+ @details
+ - Create a temporary table to store the result of the IN subquery. The
+ temporary table has one hash index on all its columns.
+ - Create a new result sink that sends the result stream of the subquery to
+ the temporary table,
+
+ @notice:
+ Currently Item_subselect::init() already chooses and creates at parse
+ time an engine with a corresponding JOIN to execute the subquery.
+
+ @retval TRUE if error
+ @retval FALSE otherwise
+*/
+
+bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
+{
+ /* Options to create_tmp_table. */
+ ulonglong tmp_create_options= thd->options | TMP_TABLE_ALL_COLUMNS;
+ /* | TMP_TABLE_FORCE_MYISAM; TIMOUR: force MYISAM */
+
+ DBUG_ENTER("subselect_hash_sj_engine::init_permanent");
+
+ if (bitmap_init_memroot(&non_null_key_parts, tmp_columns->elements,
+ thd->mem_root) ||
+ bitmap_init_memroot(&partial_match_key_parts, tmp_columns->elements,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
+
+ /*
+ Create and initialize a select result interceptor that stores the
+ result stream in a temporary table. The temporary table itself is
+ managed (created/filled/etc) internally by the interceptor.
+ */
+/*
+ TIMOUR:
+ Select a more efficient result sink when we know there is no need to collect
+ data statistics.
+
+ if (strategy == COMPLETE_MATCH)
+ {
+ if (!(result= new select_union))
+ DBUG_RETURN(TRUE);
+ }
+ else if (strategy == PARTIAL_MATCH)
+ {
+ if (!(result= new select_materialize_with_stats))
+ DBUG_RETURN(TRUE);
+ }
+*/
+ if (!(result= new select_materialize_with_stats))
+ DBUG_RETURN(TRUE);
+
+ if (((select_union*) result)->create_result_table(
+ thd, tmp_columns, TRUE, tmp_create_options,
+ "materialized subselect", TRUE))
+ DBUG_RETURN(TRUE);
+
+ tmp_table= ((select_union*) result)->table;
+
+ /*
+ If the subquery has blobs, or the total key lenght is bigger than
+ some length, or the total number of key parts is more than the
+ allowed maximum (currently MAX_REF_PARTS == 16), then the created
+ index cannot be used for lookups and we can't use hash semi
+ join. If this is the case, delete the temporary table since it
+ will not be used, and tell the caller we failed to initialize the
+ engine.
+ */
+ if (tmp_table->s->keys == 0)
+ {
+ DBUG_ASSERT(
+ tmp_table->s->uniques ||
+ tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
+ tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
+ free_tmp_table(thd, tmp_table);
+ tmp_table= NULL;
+ delete result;
+ result= NULL;
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ Make sure there is only one index on the temp table, and it doesn't have
+ the extra key part created when s->uniques > 0.
+ */
+ DBUG_ASSERT(tmp_table->s->keys == 1 &&
+ ((Item_in_subselect *) item)->left_expr->cols() ==
+ tmp_table->key_info->key_parts);
+
+ if (make_semi_join_conds() ||
+ /* A unique_engine is used both for complete and partial matching. */
+ !(lookup_engine= make_unique_engine()))
+ DBUG_RETURN(TRUE);
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ Create an artificial condition to post-filter those rows matched by index
+ lookups that cannot be distinguished by the index lookup procedure.
+
+ @notes
+ The need for post-filtering may occur e.g. because of
+ truncation. Prepared statements execution requires that fix_fields is
+ called for every execution. In order to call fix_fields we need to
+ create a Name_resolution_context and a corresponding TABLE_LIST for
+ the temporary table for the subquery, so that all column references
+ to the materialized subquery table can be resolved correctly.
+
+ @returns
+ @retval TRUE memory allocation error occurred
+ @retval FALSE the conditions were created and resolved (fixed)
+*/
+
+bool subselect_hash_sj_engine::make_semi_join_conds()
+{
+ /*
+ Table reference for tmp_table that is used to resolve column references
+ (Item_fields) to columns in tmp_table.
+ */
+ TABLE_LIST *tmp_table_ref;
+ /* Name resolution context for all tmp_table columns created below. */
+ Name_resolution_context *context;
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+
+ DBUG_ENTER("subselect_hash_sj_engine::make_semi_join_conds");
+ DBUG_ASSERT(semi_join_conds == NULL);
+
+ if (!(semi_join_conds= new Item_cond_and))
+ DBUG_RETURN(TRUE);
+
+ if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
+ DBUG_RETURN(TRUE);
+
+ tmp_table_ref->init_one_table("", "materialized subselect", TL_READ);
+ tmp_table_ref->table= tmp_table;
+
+ context= new Name_resolution_context;
+ context->init();
+ context->first_name_resolution_table=
+ context->last_name_resolution_table= tmp_table_ref;
+
+ for (uint i= 0; i < item_in->left_expr->cols(); i++)
+ {
+ Item_func_eq *eq_cond; /* New equi-join condition for the current column. */
+ /* Item for the corresponding field from the materialized temp table. */
+ Item_field *right_col_item;
+
+ if (!(right_col_item= new Item_field(thd, context, tmp_table->field[i])) ||
+ !(eq_cond= new Item_func_eq(item_in->left_expr->element_index(i),
+ right_col_item)) ||
+ (((Item_cond_and*)semi_join_conds)->add(eq_cond)))
+ {
+ delete semi_join_conds;
+ semi_join_conds= NULL;
+ DBUG_RETURN(TRUE);
+ }
+ }
+ if (semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds))
+ DBUG_RETURN(TRUE);
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Create a new uniquesubquery engine for the execution of an IN predicate.
+
+ @details
+ Create and initialize a new JOIN_TAB, and Table_ref objects to perform
+ lookups into the indexed temporary table.
+
+ @retval A new subselect_hash_sj_engine object
+ @retval NULL if a memory allocation error occurs
+*/
+
+subselect_uniquesubquery_engine*
+subselect_hash_sj_engine::make_unique_engine()
+{
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+ Item_iterator_row it(item_in->left_expr);
+ /* The only index on the temporary table. */
+ KEY *tmp_key= tmp_table->key_info;
+ JOIN_TAB *tab;
+
+ DBUG_ENTER("subselect_hash_sj_engine::make_unique_engine");
+
+ /*
+ Create and initialize the JOIN_TAB that represents an index lookup
+ plan operator into the materialized subquery result. Notice that:
+ - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
+ - here we initialize only those members that are used by
+ subselect_uniquesubquery_engine, so these objects are incomplete.
+ */
+ if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
+ DBUG_RETURN(NULL);
+
+ tab->table= tmp_table;
+ tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);
+
+ DBUG_RETURN(new subselect_uniquesubquery_engine(thd, tab, item,
+ semi_join_conds));
+}
+
+
+/**
+ Initialize members of the engine that need to be re-initilized at each
+ execution.
+
+ @retval TRUE if a memory allocation error occurred
+ @retval FALSE if success
+*/
+
+bool subselect_hash_sj_engine::init_runtime()
+{
+ /*
+ Create and optimize the JOIN that will be used to materialize
+ the subquery if not yet created.
+ */
+ materialize_engine->prepare();
+ /*
+ Repeat name resolution for 'cond' since cond is not part of any
+ clause of the query, and it is not 'fixed' during JOIN::prepare.
+ */
+ if (semi_join_conds && !semi_join_conds->fixed &&
+ semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds))
+ return TRUE;
+ /* Let our engine reuse this query plan for materialization. */
+ materialize_join= materialize_engine->join;
+ materialize_join->change_result(result);
+ return FALSE;
+}
+
+
+subselect_hash_sj_engine::~subselect_hash_sj_engine()
+{
+ delete lookup_engine;
+ delete result;
+ if (tmp_table)
+ free_tmp_table(thd, tmp_table);
+}
+
+
+/**
+ Cleanup performed after each PS execution.
+
+ @details
+ Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
+*/
+
+void subselect_hash_sj_engine::cleanup()
+{
+ enum_engine_type lookup_engine_type= lookup_engine->engine_type();
+ is_materialized= FALSE;
+ bitmap_clear_all(&non_null_key_parts);
+ bitmap_clear_all(&partial_match_key_parts);
+ count_partial_match_columns= 0;
+ count_null_only_columns= 0;
+ strategy= UNDEFINED;
+ materialize_engine->cleanup();
+ if (lookup_engine_type == TABLE_SCAN_ENGINE ||
+ lookup_engine_type == ROWID_MERGE_ENGINE)
+ {
+ subselect_engine *inner_lookup_engine;
+ inner_lookup_engine=
+ ((subselect_partial_match_engine*) lookup_engine)->lookup_engine;
+ /*
+ Partial match engines are recreated for each PS execution inside
+ subselect_hash_sj_engine::exec().
+ */
+ delete lookup_engine;
+ lookup_engine= inner_lookup_engine;
+ }
+ DBUG_ASSERT(lookup_engine->engine_type() == UNIQUESUBQUERY_ENGINE);
+ lookup_engine->cleanup();
+ result->cleanup(); /* Resets the temp table as well. */
+}
+
+
+/**
+ Execute a subquery IN predicate via materialization.
+
+ @details
+ If needed materialize the subquery into a temporary table, then
+ copmpute the predicate via a lookup into this table.
+
+ @retval TRUE if error
+ @retval FALSE otherwise
+*/
+
+int subselect_hash_sj_engine::exec()
+{
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+ SELECT_LEX *save_select= thd->lex->current_select;
+ subselect_partial_match_engine *pm_engine= NULL;
+ int res= 0;
+
+ DBUG_ENTER("subselect_hash_sj_engine::exec");
+
+ /*
+ Optimize and materialize the subquery during the first execution of
+ the subquery predicate.
+ */
+ thd->lex->current_select= materialize_engine->select_lex;
+ if ((res= materialize_join->optimize()))
+ goto err; /* purecov: inspected */
+ DBUG_ASSERT(!is_materialized); /* We should materialize only once. */
+ materialize_join->exec();
+ if ((res= test(materialize_join->error || thd->is_fatal_error)))
+ goto err;
+
+ /*
+ TODO:
+ - Unlock all subquery tables as we don't need them. To implement this
+ we need to add new functionality to JOIN::join_free that can unlock
+ all tables in a subquery (and all its subqueries).
+ - The temp table used for grouping in the subquery can be freed
+ immediately after materialization (yet it's done together with
+ unlocking).
+ */
+ is_materialized= TRUE;
+ /*
+ If the subquery returned no rows, the temporary table is empty, so we know
+ directly that the result of IN is FALSE. We first update the table
+ statistics, then we test if the temporary table for the query result is
+ empty.
+ */
+ tmp_table->file->info(HA_STATUS_VARIABLE);
+ if (!tmp_table->file->stats.records)
+ {
+ item_in->value= FALSE;
+ /* The value of IN will not change during this execution. */
+ item_in->is_constant= TRUE;
+ item_in->set_first_execution();
+ /* TIMOUR: check if we need this: item_in->null_value= FALSE; */
+ DBUG_RETURN(FALSE);
+ }
+
+ /*
+ TIMOUR: The schema-based analysis for partial matching can be done once for
+ prepared statement and remembered. It is done here to remove the need to
+ save/restore all related variables between each re-execution, thus making
+ the code simpler.
+ */
+ strategy= get_strategy_using_schema();
+ /* This call may discover that we don't need partial matching at all. */
+ strategy= get_strategy_using_data();
+ if (strategy == PARTIAL_MATCH)
+ {
+ uint count_pm_keys; /* Total number of keys needed for partial matching. */
+ MY_BITMAP *nn_key_parts; /* The key parts of the only non-NULL index. */
+ uint covering_null_row_width;
+ select_materialize_with_stats *result_sink=
+ (select_materialize_with_stats *) result;
+
+ nn_key_parts= (count_partial_match_columns < tmp_table->s->fields) ?
+ &non_null_key_parts : NULL;
+
+ if (result_sink->get_max_nulls_in_row() ==
+ tmp_table->s->fields -
+ (nn_key_parts ? bitmap_bits_set(nn_key_parts) : 0))
+ covering_null_row_width= result_sink->get_max_nulls_in_row();
+ else
+ covering_null_row_width= 0;
+
+ if (covering_null_row_width)
+ count_pm_keys= nn_key_parts ? 1 : 0;
+ else
+ count_pm_keys= count_partial_match_columns - count_null_only_columns +
+ (nn_key_parts ? 1 : 0);
+
+ choose_partial_match_strategy(test(nn_key_parts),
+ test(covering_null_row_width),
+ &partial_match_key_parts);
+ DBUG_ASSERT(strategy == PARTIAL_MATCH_MERGE ||
+ strategy == PARTIAL_MATCH_SCAN);
+ if (strategy == PARTIAL_MATCH_MERGE)
+ {
+ pm_engine=
+ new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*)
+ lookup_engine, tmp_table,
+ count_pm_keys,
+ covering_null_row_width,
+ item, result,
+ semi_join_conds->argument_list());
+ if (!pm_engine ||
+ ((subselect_rowid_merge_engine*) pm_engine)->
+ init(nn_key_parts, &partial_match_key_parts))
+ {
+ /*
+ The call to init() would fail if there was not enough memory to allocate
+ all buffers for the rowid merge strategy. In this case revert to table
+ scanning which doesn't need any big buffers.
+ */
+ delete pm_engine;
+ pm_engine= NULL;
+ strategy= PARTIAL_MATCH_SCAN;
+ }
+ }
+
+ if (strategy == PARTIAL_MATCH_SCAN)
+ {
+ if (!(pm_engine=
+ new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*)
+ lookup_engine, tmp_table,
+ item, result,
+ semi_join_conds->argument_list(),
+ covering_null_row_width)))
+ {
+ /* This is an irrecoverable error. */
+ res= 1;
+ goto err;
+ }
+ }
+ }
+
+ if (pm_engine)
+ lookup_engine= pm_engine;
+ item_in->change_engine(lookup_engine);
+
+err:
+ thd->lex->current_select= save_select;
+ DBUG_RETURN(res);
+}
+
+
+/**
+ Print the state of this engine into a string for debugging and views.
+*/
+
+void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
+{
+ str->append(STRING_WITH_LEN(" <materialize> ("));
+ materialize_engine->print(str, query_type);
+ str->append(STRING_WITH_LEN(" ), "));
+
+ if (lookup_engine)
+ lookup_engine->print(str, query_type);
+ else
+ str->append(STRING_WITH_LEN(
+ "<engine selected at execution time>"
+ ));
+}
+
+void subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
+{
+ DBUG_ASSERT(FALSE);
+}
+
+void subselect_hash_sj_engine::exclude()
+{
+ DBUG_ASSERT(FALSE);
+}
+
+bool subselect_hash_sj_engine::no_tables()
+{
+ DBUG_ASSERT(FALSE);
+ return FALSE;
+}
+
+bool subselect_hash_sj_engine::change_result(Item_subselect *si,
+ select_result_interceptor *res)
+{
+ DBUG_ASSERT(FALSE);
+ return TRUE;
+}
+
+
+Ordered_key::Ordered_key(uint keyid_arg, TABLE *tbl_arg, Item *search_key_arg,
+ ha_rows null_count_arg, ha_rows min_null_row_arg,
+ ha_rows max_null_row_arg, uchar *row_num_to_rowid_arg)
+ : keyid(keyid_arg), tbl(tbl_arg), search_key(search_key_arg),
+ row_num_to_rowid(row_num_to_rowid_arg), null_count(null_count_arg)
+{
+ DBUG_ASSERT(tbl->file->stats.records > null_count);
+ key_buff_elements= tbl->file->stats.records - null_count;
+ cur_key_idx= HA_POS_ERROR;
+
+ DBUG_ASSERT((null_count && min_null_row_arg && max_null_row_arg) ||
+ (!null_count && !min_null_row_arg && !max_null_row_arg));
+ if (null_count)
+ {
+ /* The counters are 1-based, for key access we need 0-based indexes. */
+ min_null_row= min_null_row_arg - 1;
+ max_null_row= max_null_row_arg - 1;
+ }
+ else
+ min_null_row= max_null_row= 0;
+}
+
+
+Ordered_key::~Ordered_key()
+{
+ my_free((char*) key_buff, MYF(0));
+ bitmap_free(&null_key);
+}
+
+
+/*
+ Cleanup that needs to be done for each PS (re)execution.
+*/
+
+void Ordered_key::cleanup()
+{
+ /*
+ Currently these keys are recreated for each PS re-execution, thus
+ there is nothing to cleanup, the whole object goes away after execution
+ is over. All handler related initialization/deinitialization is done by
+ the parent subselect_rowid_merge_engine object.
+ */
+}
+
+
+/*
+ Initialize a multi-column index.
+*/
+
+bool Ordered_key::init(MY_BITMAP *columns_to_index)
+{
+ THD *thd= tbl->in_use;
+ uint cur_key_col= 0;
+ Item_field *cur_tmp_field;
+ 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*));
+
+ for (uint i= 0; i < columns_to_index->n_bits; i++)
+ {
+ if (!bitmap_is_set(columns_to_index, i))
+ continue;
+ cur_tmp_field= new Item_field(tbl->field[i]);
+ /* Create the predicate (tmp_column[i] < outer_ref[i]). */
+ fn_less_than= new Item_func_lt(cur_tmp_field,
+ search_key->element_index(i));
+ fn_less_than->fix_fields(thd, (Item**) &fn_less_than);
+ key_columns[cur_key_col]= cur_tmp_field;
+ compare_pred[cur_key_col]= fn_less_than;
+ ++cur_key_col;
+ }
+
+ if (alloc_keys_buffers())
+ {
+ /* TIMOUR revert to partial match via table scan. */
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Initialize a single-column index.
+*/
+
+bool Ordered_key::init(int col_idx)
+{
+ THD *thd= tbl->in_use;
+
+ key_column_count= 1;
+
+ // TIMOUR: check for mem allocation err, revert to scan
+
+ key_columns= (Item_field**) thd->alloc(sizeof(Item_field*));
+ compare_pred= (Item_func_lt**) thd->alloc(sizeof(Item_func_lt*));
+
+ key_columns[0]= new Item_field(tbl->field[col_idx]);
+ /* Create the predicate (tmp_column[i] < outer_ref[i]). */
+ compare_pred[0]= new Item_func_lt(key_columns[0],
+ search_key->element_index(col_idx));
+ compare_pred[0]->fix_fields(thd, (Item**)&compare_pred[0]);
+
+ if (alloc_keys_buffers())
+ {
+ /* TIMOUR revert to partial match via table scan. */
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Allocate the buffers for both the row number, and the NULL-bitmap indexes.
+*/
+
+bool Ordered_key::alloc_keys_buffers()
+{
+ DBUG_ASSERT(key_buff_elements > 0);
+
+ if (!(key_buff= (rownum_t*) my_malloc(key_buff_elements * sizeof(rownum_t),
+ MYF(MY_WME))))
+ return TRUE;
+
+ /*
+ TIMOUR: it is enough to create bitmaps with size
+ (max_null_row - min_null_row), and then use min_null_row as
+ lookup offset.
+ */
+ /* Notice that max_null_row is max array index, we need count, so +1. */
+ if (bitmap_init(&null_key, NULL, max_null_row + 1, FALSE))
+ return TRUE;
+
+ cur_key_idx= HA_POS_ERROR;
+
+ return FALSE;
+}
+
+
+/*
+ Quick sort comparison function that compares two rows of the same table
+ indentfied with their row numbers.
+
+ @retval -1
+ @retval 0
+ @retval +1
+*/
+
+int
+Ordered_key::cmp_keys_by_row_data(ha_rows a, ha_rows b)
+{
+ uchar *rowid_a, *rowid_b;
+ int error, cmp_res;
+ /* The length in bytes of the rowids (positions) of tmp_table. */
+ uint rowid_length= tbl->file->ref_length;
+
+ if (a == b)
+ return 0;
+ /* Get the corresponding rowids. */
+ rowid_a= row_num_to_rowid + a * rowid_length;
+ rowid_b= row_num_to_rowid + b * rowid_length;
+ /* Fetch the rows for comparison. */
+ error= tbl->file->ha_rnd_pos(tbl->record[0], rowid_a);
+ DBUG_ASSERT(!error);
+ error= tbl->file->ha_rnd_pos(tbl->record[1], rowid_b);
+ DBUG_ASSERT(!error);
+ /*
+ Compare the two rows by the corresponding values of the indexed
+ columns.
+ */
+ for (uint i= 0; i < key_column_count; i++)
+ {
+ Field *cur_field= key_columns[i]->field;
+ if ((cmp_res= cur_field->cmp_offset(tbl->s->rec_buff_length)))
+ return (cmp_res > 0 ? 1 : -1);
+ }
return 0;
}
+
+
+int
+Ordered_key::cmp_keys_by_row_data_and_rownum(Ordered_key *key,
+ rownum_t* a, rownum_t* b)
+{
+ /* The result of comparing the two keys according to their row data. */
+ int cmp_row_res= key->cmp_keys_by_row_data(*a, *b);
+ if (cmp_row_res)
+ return cmp_row_res;
+ return (*a < *b) ? -1 : (*a > *b) ? 1 : 0;
+}
+
+
+void Ordered_key::sort_keys()
+{
+ my_qsort2(key_buff, key_buff_elements, sizeof(rownum_t),
+ (qsort2_cmp) &cmp_keys_by_row_data_and_rownum, (void*) this);
+ /* Invalidate the current row position. */
+ cur_key_idx= HA_POS_ERROR;
+}
+
+
+/*
+ The fraction of rows that do not contain NULL in the columns indexed by
+ this key.
+
+ @retval 1 if there are no NULLs
+ @retval 0 if only NULLs
+*/
+
+double Ordered_key::null_selectivity()
+{
+ /* We should not be processing empty tables. */
+ DBUG_ASSERT(tbl->file->stats.records);
+ return (1 - (double) null_count / (double) tbl->file->stats.records);
+}
+
+
+/*
+ Compare the value(s) of the current key in 'search_key' with the
+ data of the current table record.
+
+ @notes The comparison result follows from the way compare_pred
+ is created in Ordered_key::init. Currently compare_pred compares
+ a field in of the current row with the corresponding Item that
+ contains the search key.
+
+ @param row_num Number of the row (not index in the key_buff array)
+
+ @retval -1 if (current row < search_key)
+ @retval 0 if (current row == search_key)
+ @retval +1 if (current row > search_key)
+*/
+
+int Ordered_key::cmp_key_with_search_key(rownum_t row_num)
+{
+ /* The length in bytes of the rowids (positions) of tmp_table. */
+ uint rowid_length= tbl->file->ref_length;
+ uchar *cur_rowid= row_num_to_rowid + row_num * rowid_length;
+ int error, cmp_res;
+
+ error= tbl->file->ha_rnd_pos(tbl->record[0], cur_rowid);
+ DBUG_ASSERT(!error);
+
+ for (uint i= 0; i < key_column_count; i++)
+ {
+ cmp_res= compare_pred[i]->get_comparator()->compare();
+ /* Unlike Arg_comparator::compare_row() here there should be no NULLs. */
+ DBUG_ASSERT(!compare_pred[i]->null_value);
+ if (cmp_res)
+ return (cmp_res > 0 ? 1 : -1);
+ }
+ return 0;
+}
+
+
+/*
+ Find a key in a sorted array of keys via binary search.
+
+ see create_subq_in_equalities()
+*/
+
+bool Ordered_key::lookup()
+{
+ DBUG_ASSERT(key_buff_elements);
+
+ ha_rows lo= 0;
+ ha_rows hi= key_buff_elements - 1;
+ ha_rows mid;
+ int cmp_res;
+
+ while (lo <= hi)
+ {
+ mid= lo + (hi - lo) / 2;
+ cmp_res= cmp_key_with_search_key(key_buff[mid]);
+ /*
+ In order to find the minimum match, check if the pevious element is
+ equal or smaller than the found one. If equal, we need to search further
+ to the left.
+ */
+ if (!cmp_res && mid > 0)
+ cmp_res= !cmp_key_with_search_key(key_buff[mid - 1]) ? 1 : 0;
+
+ if (cmp_res == -1)
+ {
+ /* row[mid] < search_key */
+ lo= mid + 1;
+ }
+ else if (cmp_res == 1)
+ {
+ /* row[mid] > search_key */
+ if (!mid)
+ goto not_found;
+ hi= mid - 1;
+ }
+ else
+ {
+ /* row[mid] == search_key */
+ cur_key_idx= mid;
+ return TRUE;
+ }
+ }
+not_found:
+ cur_key_idx= HA_POS_ERROR;
+ return FALSE;
+}
+
+
+/*
+ Move the current index pointer to the next key with the same column
+ values as the current key. Since the index is sorted, all such keys
+ are contiguous.
+*/
+
+bool Ordered_key::next_same()
+{
+ DBUG_ASSERT(key_buff_elements);
+
+ if (cur_key_idx < key_buff_elements - 1)
+ {
+ /*
+ TIMOUR:
+ The below is quite inefficient, since as a result we will fetch every
+ row (except the last one) twice. There must be a more efficient way,
+ e.g. swapping record[0] and record[1], and reading only the new record.
+ */
+ if (!cmp_keys_by_row_data(key_buff[cur_key_idx], key_buff[cur_key_idx + 1]))
+ {
+ ++cur_key_idx;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void Ordered_key::print(String *str)
+{
+ uint i;
+ str->append("{idx=");
+ str->qs_append(keyid);
+ str->append(", (");
+ for (i= 0; i < key_column_count - 1; i++)
+ {
+ str->append(key_columns[i]->field->field_name);
+ str->append(", ");
+ }
+ str->append(key_columns[i]->field->field_name);
+ str->append("), ");
+
+ str->append("null_bitmap: (bits=");
+ str->qs_append(null_key.n_bits);
+ str->append(", nulls= ");
+ str->qs_append((double)null_count);
+ str->append(", min_null= ");
+ str->qs_append((double)min_null_row);
+ str->append(", max_null= ");
+ str->qs_append((double)max_null_row);
+ str->append("), ");
+
+ str->append('}');
+}
+
+
+subselect_partial_match_engine::subselect_partial_match_engine(
+ THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
+ TABLE *tmp_table_arg, Item_subselect *item_arg,
+ select_result_interceptor *result_arg,
+ List<Item> *equi_join_conds_arg,
+ uint covering_null_row_width_arg)
+ :subselect_engine(thd_arg, item_arg, result_arg),
+ tmp_table(tmp_table_arg), lookup_engine(engine_arg),
+ equi_join_conds(equi_join_conds_arg),
+ covering_null_row_width(covering_null_row_width_arg)
+{}
+
+
+int subselect_partial_match_engine::exec()
+{
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+ int res;
+
+ /* Try to find a matching row by index lookup. */
+ res= lookup_engine->copy_ref_key_simple();
+ if (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)
+ {
+ /* Search for a complete match. */
+ if ((res= lookup_engine->index_lookup()))
+ {
+ /* An error occured during lookup(). */
+ item_in->value= 0;
+ item_in->null_value= 0;
+ return res;
+ }
+ else if (item_in->value)
+ {
+ /*
+ A complete match was found, the result of IN is TRUE.
+ Notice: (this->item == lookup_engine->item)
+ */
+ return 0;
+ }
+ }
+
+ if (covering_null_row_width == tmp_table->s->fields)
+ {
+ /*
+ If there is a NULL-only row that coveres all columns the result of IN
+ is UNKNOWN.
+ */
+ item_in->value= 0;
+ /*
+ TIMOUR: which one is the right way to propagate an UNKNOWN result?
+ Should we also set empty_result_set= FALSE; ???
+ */
+ //item_in->was_null= 1;
+ item_in->null_value= 1;
+ return 0;
+ }
+
+ /*
+ There is no complete match. Look for a partial match (UNKNOWN result), or
+ no match (FALSE).
+ */
+ if (tmp_table->file->inited)
+ tmp_table->file->ha_index_end();
+
+ if (partial_match())
+ {
+ /* The result of IN is UNKNOWN. */
+ item_in->value= 0;
+ /*
+ TIMOUR: which one is the right way to propagate an UNKNOWN result?
+ Should we also set empty_result_set= FALSE; ???
+ */
+ //item_in->was_null= 1;
+ item_in->null_value= 1;
+ }
+ else
+ {
+ /* The result of IN is FALSE. */
+ item_in->value= 0;
+ /*
+ TIMOUR: which one is the right way to propagate an UNKNOWN result?
+ Should we also set empty_result_set= FALSE; ???
+ */
+ //item_in->was_null= 0;
+ item_in->null_value= 0;
+ }
+
+ return 0;
+}
+
+
+void subselect_partial_match_engine::print(String *str,
+ enum_query_type query_type)
+{
+ /*
+ Should never be called as the actual engine cannot be known at query
+ optimization time.
+ DBUG_ASSERT(FALSE);
+ */
+}
+
+
+/*
+ @param non_null_key_parts
+ @param partial_match_key_parts A union of all single-column NULL key parts.
+ @param count_partial_match_columns Number of NULL keyparts (set bits above).
+
+ @retval FALSE the engine was initialized successfully
+ @retval TRUE there was some (memory allocation) error during initialization,
+ such errors should be interpreted as revert to other strategy
+*/
+
+bool
+subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
+ MY_BITMAP *partial_match_key_parts)
+{
+ /* The length in bytes of the rowids (positions) of tmp_table. */
+ uint rowid_length= tmp_table->file->ref_length;
+ ha_rows row_count= tmp_table->file->stats.records;
+ rownum_t cur_rownum= 0;
+ select_materialize_with_stats *result_sink=
+ (select_materialize_with_stats *) result;
+ uint cur_keyid= 0;
+ Item_in_subselect *item_in= (Item_in_subselect*) item;
+ int error;
+
+ if (keys_count == 0)
+ {
+ /* There is nothing to initialize, we will only do regular lookups. */
+ return FALSE;
+ }
+
+ DBUG_ASSERT(!covering_null_row_width || (covering_null_row_width &&
+ keys_count == 1 &&
+ non_null_key_parts));
+ /*
+ Allocate buffers to hold the merged keys and the mapping between rowids and
+ row numbers.
+ */
+ if (!(merge_keys= (Ordered_key**) thd->alloc(keys_count *
+ sizeof(Ordered_key*))) ||
+ !(row_num_to_rowid= (uchar*) my_malloc(row_count * rowid_length *
+ sizeof(uchar), MYF(MY_WME))))
+ return TRUE;
+
+ /* Create the only non-NULL key if there is any. */
+ if (non_null_key_parts)
+ {
+ non_null_key= new Ordered_key(cur_keyid, tmp_table, item_in->left_expr,
+ 0, 0, 0, row_num_to_rowid);
+ if (non_null_key->init(non_null_key_parts))
+ return TRUE;
+ merge_keys[cur_keyid]= non_null_key;
+ merge_keys[cur_keyid]->first();
+ ++cur_keyid;
+ }
+
+ /*
+ If there is a covering NULL row, the only key that is needed is the
+ only non-NULL key that is already created above. We create keys on
+ NULL-able columns only if there is no covering NULL row.
+ */
+ if (!covering_null_row_width)
+ {
+ if (bitmap_init_memroot(&matching_keys, keys_count, thd->mem_root) ||
+ bitmap_init_memroot(&matching_outer_cols, keys_count, thd->mem_root) ||
+ bitmap_init_memroot(&null_only_columns, keys_count, thd->mem_root))
+ return TRUE;
+
+ /*
+ Create one single-column NULL-key for each column in
+ partial_match_key_parts.
+ */
+ for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
+ {
+ if (!bitmap_is_set(partial_match_key_parts, i))
+ continue;
+
+ if (result_sink->get_null_count_of_col(i) == row_count)
+ {
+ bitmap_set_bit(&null_only_columns, cur_keyid);
+ continue;
+ }
+ else
+ {
+ merge_keys[cur_keyid]= new Ordered_key(
+ cur_keyid, tmp_table,
+ item_in->left_expr->element_index(i),
+ result_sink->get_null_count_of_col(i),
+ result_sink->get_min_null_of_col(i),
+ result_sink->get_max_null_of_col(i),
+ row_num_to_rowid);
+ if (merge_keys[cur_keyid]->init(i))
+ return TRUE;
+ merge_keys[cur_keyid]->first();
+ }
+ ++cur_keyid;
+ }
+ }
+ DBUG_ASSERT(cur_keyid == keys_count);
+
+ /* Populate the indexes with data from the temporary table. */
+ if (tmp_table->file->ha_rnd_init_with_error(1))
+ return TRUE;
+ tmp_table->file->extra_opt(HA_EXTRA_CACHE,
+ current_thd->variables.read_buff_size);
+ tmp_table->null_row= 0;
+ while (TRUE)
+ {
+ error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
+ if (error == HA_ERR_RECORD_DELETED)
+ {
+ /* We get this for duplicate records that should not be in tmp_table. */
+ continue;
+ }
+ /*
+ This is a temp table that we fully own, there should be no other
+ cause to stop the iteration than EOF.
+ */
+ DBUG_ASSERT(!error || error == HA_ERR_END_OF_FILE);
+ if (error == HA_ERR_END_OF_FILE)
+ {
+ DBUG_ASSERT(cur_rownum == tmp_table->file->stats.records);
+ break;
+ }
+
+ /*
+ Save the position of this record in the row_num -> rowid mapping.
+ */
+ tmp_table->file->position(tmp_table->record[0]);
+ memcpy(row_num_to_rowid + cur_rownum * rowid_length,
+ tmp_table->file->ref, rowid_length);
+
+ /* Add the current row number to the corresponding keys. */
+ if (non_null_key)
+ {
+ /* By definition there are no NULLs in the non-NULL key. */
+ non_null_key->add_key(cur_rownum);
+ }
+
+ for (uint i= (non_null_key ? 1 : 0); i < keys_count; i++)
+ {
+ /*
+ Check if the first and only indexed column contains NULL in the curent
+ row, and add the row number to the corresponding key.
+ */
+ if (tmp_table->field[merge_keys[i]->get_field_idx(0)]->is_null())
+ merge_keys[i]->set_null(cur_rownum);
+ else
+ merge_keys[i]->add_key(cur_rownum);
+ }
+ ++cur_rownum;
+ }
+
+ tmp_table->file->ha_rnd_end();
+
+ /* Sort all the keys by their NULL selectivity. */
+ my_qsort(merge_keys, keys_count, sizeof(Ordered_key*),
+ (qsort_cmp) cmp_keys_by_null_selectivity);
+
+ /* Sort the keys in each of the indexes. */
+ for (uint i= 0; i < keys_count; i++)
+ merge_keys[i]->sort_keys();
+
+ if (init_queue(&pq, keys_count, 0, FALSE,
+ subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
+ 0, 0))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+subselect_rowid_merge_engine::~subselect_rowid_merge_engine()
+{
+ /* None of the resources below is allocated if there are no ordered keys. */
+ if (keys_count)
+ {
+ my_free((char*) row_num_to_rowid, MYF(0));
+ for (uint i= 0; i < keys_count; i++)
+ delete merge_keys[i];
+ delete_queue(&pq);
+ if (tmp_table->file->inited == handler::RND)
+ tmp_table->file->ha_rnd_end();
+ }
+}
+
+
+void subselect_rowid_merge_engine::cleanup()
+{
+}
+
+
+/*
+ Quick sort comparison function to compare keys in order of decreasing bitmap
+ selectivity, so that the most selective keys come first.
+
+ @param k1 first key to compare
+ @param k2 second key to compare
+
+ @retval 1 if k1 is less selective than k2
+ @retval 0 if k1 is equally selective as k2
+ @retval -1 if k1 is more selective than k2
+*/
+
+int
+subselect_rowid_merge_engine::cmp_keys_by_null_selectivity(Ordered_key **k1,
+ Ordered_key **k2)
+{
+ double k1_sel= (*k1)->null_selectivity();
+ double k2_sel= (*k2)->null_selectivity();
+ if (k1_sel < k2_sel)
+ return 1;
+ if (k1_sel > k2_sel)
+ return -1;
+ return 0;
+}
+
+
+/*
+*/
+
+int
+subselect_rowid_merge_engine::cmp_keys_by_cur_rownum(void *arg,
+ uchar *k1, uchar *k2)
+{
+ rownum_t r1= ((Ordered_key*) k1)->current();
+ rownum_t r2= ((Ordered_key*) k2)->current();
+
+ return (r1 < r2) ? -1 : (r1 > r2) ? 1 : 0;
+}
+
+
+/*
+ Check if certain table row contains a NULL in all columns for which there is
+ no match in the corresponding value index.
+
+ @retval TRUE if a NULL row exists
+ @retval FALSE otherwise
+*/
+
+bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
+{
+ Ordered_key *cur_key;
+ uint cur_id;
+ for (uint i = 0; i < keys_count; i++)
+ {
+ cur_key= merge_keys[i];
+ cur_id= cur_key->get_keyid();
+ if (bitmap_is_set(&matching_keys, cur_id))
+ {
+ /*
+ The key 'i' (with id 'cur_keyid') already matches a value in row 'row_num',
+ thus we skip it as it can't possibly match a NULL.
+ */
+ continue;
+ }
+ if (!cur_key->is_null(row_num))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ @retval TRUE there is a partial match (UNKNOWN)
+ @retval FALSE there is no match at all (FALSE)
+*/
+
+bool subselect_rowid_merge_engine::partial_match()
+{
+ Ordered_key *min_key; /* Key that contains the current minimum position. */
+ rownum_t min_row_num; /* Current row number of min_key. */
+ Ordered_key *cur_key;
+ rownum_t cur_row_num;
+ uint count_nulls_in_search_key= 0;
+ bool res= FALSE;
+
+ /* If there is a non-NULL key, it must be the first key in the keys array. */
+ DBUG_ASSERT(!non_null_key || (non_null_key && merge_keys[0] == non_null_key));
+ /* The prioryty queue for keys must be empty. */
+ DBUG_ASSERT(!pq.elements);
+
+ /* All data accesses during execution are via handler::ha_rnd_pos() */
+ if (tmp_table->file->ha_rnd_init_with_error(0))
+ {
+ res= FALSE;
+ goto end;
+ }
+
+ /* Check if there is a match for the columns of the only non-NULL key. */
+ if (non_null_key && !non_null_key->lookup())
+ {
+ res= FALSE;
+ goto end;
+ }
+
+ /*
+ If there is a NULL (sub)row that covers all NULL-able columns,
+ then there is a guranteed partial match, and we don't need to search
+ for the matching row.
+ */
+ if (covering_null_row_width)
+ {
+ res= TRUE;
+ goto end;
+ }
+
+ if (non_null_key)
+ queue_insert(&pq, (uchar *) non_null_key);
+ /*
+ Do not add the non_null_key, since it was already processed above.
+ */
+ bitmap_clear_all(&matching_outer_cols);
+ for (uint i= test(non_null_key); i < keys_count; i++)
+ {
+ DBUG_ASSERT(merge_keys[i]->get_column_count() == 1);
+ if (merge_keys[i]->get_search_key(0)->is_null())
+ {
+ ++count_nulls_in_search_key;
+ bitmap_set_bit(&matching_outer_cols, merge_keys[i]->get_keyid());
+ }
+ else if (merge_keys[i]->lookup())
+ queue_insert(&pq, (uchar *) merge_keys[i]);
+ }
+
+ /*
+ If the outer reference consists of only NULLs, or if it has NULLs in all
+ nullable columns, 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))
+ {
+ res= TRUE;
+ 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.
+ */
+ if (pq.elements - test(non_null_key) == 0)
+ {
+ res= FALSE;
+ goto end;
+ }
+
+ DBUG_ASSERT(pq.elements);
+
+ min_key= (Ordered_key*) queue_remove_top(&pq);
+ min_row_num= min_key->current();
+ bitmap_copy(&matching_keys, &null_only_columns);
+ bitmap_set_bit(&matching_keys, min_key->get_keyid());
+ bitmap_union(&matching_keys, &matching_outer_cols);
+ if (min_key->next_same())
+ queue_insert(&pq, (uchar *) min_key);
+
+ if (pq.elements == 0)
+ {
+ /*
+ Check the only matching row of the only key min_key for NULL matches
+ in the other columns.
+ */
+ res= test_null_row(min_row_num);
+ goto end;
+ }
+
+ while (TRUE)
+ {
+ cur_key= (Ordered_key*) queue_remove_top(&pq);
+ cur_row_num= cur_key->current();
+
+ if (cur_row_num == min_row_num)
+ bitmap_set_bit(&matching_keys, cur_key->get_keyid());
+ else
+ {
+ /* Follows from the correct use of priority queue. */
+ DBUG_ASSERT(cur_row_num > min_row_num);
+ if (test_null_row(min_row_num))
+ {
+ res= TRUE;
+ goto end;
+ }
+ else
+ {
+ min_key= cur_key;
+ min_row_num= cur_row_num;
+ bitmap_copy(&matching_keys, &null_only_columns);
+ bitmap_set_bit(&matching_keys, min_key->get_keyid());
+ bitmap_union(&matching_keys, &matching_outer_cols);
+ }
+ }
+
+ if (cur_key->next_same())
+ queue_insert(&pq, (uchar *) cur_key);
+
+ if (pq.elements == 0)
+ {
+ /* Check the last row of the last column in PQ for NULL matches. */
+ res= test_null_row(min_row_num);
+ goto end;
+ }
+ }
+
+ /* We should never get here - all branches must be handled explicitly above. */
+ DBUG_ASSERT(FALSE);
+
+end:
+ queue_remove_all(&pq);
+ tmp_table->file->ha_rnd_end();
+ return res;
+}
+
+
+subselect_table_scan_engine::subselect_table_scan_engine(
+ THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
+ TABLE *tmp_table_arg,
+ Item_subselect *item_arg,
+ select_result_interceptor *result_arg,
+ List<Item> *equi_join_conds_arg,
+ uint covering_null_row_width_arg)
+ :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
+ result_arg, equi_join_conds_arg,
+ covering_null_row_width_arg)
+{}
+
+
+/*
+ TIMOUR:
+ This method is based on subselect_uniquesubquery_engine::scan_table().
+ Consider refactoring somehow, 80% of the code is the same.
+
+ for each row_i in tmp_table
+ {
+ count_matches= 0;
+ for each row element row_i[j]
+ {
+ if (outer_ref[j] is NULL || row_i[j] is NULL || outer_ref[j] == row_i[j])
+ ++count_matches;
+ }
+ if (count_matches == outer_ref.elements)
+ return TRUE
+ }
+ return FALSE
+*/
+
+bool subselect_table_scan_engine::partial_match()
+{
+ List_iterator_fast<Item> equality_it(*equi_join_conds);
+ Item *cur_eq;
+ uint count_matches;
+ int error;
+ bool res;
+
+ if (tmp_table->file->ha_rnd_init_with_error(1))
+ {
+ res= FALSE;
+ goto end;
+ }
+
+ tmp_table->file->extra_opt(HA_EXTRA_CACHE,
+ current_thd->variables.read_buff_size);
+ /*
+ TIMOUR:
+ scan_table() also calls "table->null_row= 0;", why, do we need it?
+ */
+ for (;;)
+ {
+ error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
+ if (error) {
+ if (error == HA_ERR_RECORD_DELETED)
+ {
+ error= 0;
+ continue;
+ }
+ if (error == HA_ERR_END_OF_FILE)
+ {
+ error= 0;
+ break;
+ }
+ else
+ {
+ error= report_error(tmp_table, error);
+ break;
+ }
+ }
+
+ equality_it.rewind();
+ count_matches= 0;
+ while ((cur_eq= equality_it++))
+ {
+ DBUG_ASSERT(cur_eq->type() == Item::FUNC_ITEM &&
+ ((Item_func*)cur_eq)->functype() == Item_func::EQ_FUNC);
+ if (!cur_eq->val_int() && !cur_eq->null_value)
+ break;
+ ++count_matches;
+ }
+ if (count_matches == tmp_table->s->fields)
+ {
+ res= TRUE; /* Found a matching row. */
+ goto end;
+ }
+ }
+
+ res= FALSE;
+end:
+ tmp_table->file->ha_rnd_end();
+ return res;
+}
+
+
+void subselect_table_scan_engine::cleanup()
+{
+}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 48bfaab4e3a..8d590bc4273 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -22,9 +22,11 @@
class st_select_lex;
class st_select_lex_unit;
class JOIN;
-class select_subselect;
+class select_result_interceptor;
class subselect_engine;
+class subselect_hash_sj_engine;
class Item_bool_func2;
+class Cached_item;
/* base class for subselects */
@@ -34,10 +36,24 @@ class Item_subselect :public Item_result_field
protected:
/* thread handler, will be assigned in fix_fields only */
THD *thd;
- /* substitution instead of subselect in case of optimization */
+ /*
+ Used inside Item_subselect::fix_fields() according to this scenario:
+ > Item_subselect::fix_fields
+ > engine->prepare
+ > child_join->prepare
+ (Here we realize we need to do the rewrite and set
+ substitution= some new Item, eg. Item_in_optimizer )
+ < child_join->prepare
+ < engine->prepare
+ *ref= substitution;
+ < Item_subselect::fix_fields
+ */
Item *substitution;
+public:
/* unit of subquery */
st_select_lex_unit *unit;
+protected:
+ Item *expr_cache;
/* engine that perform execution of subselect (single select or union) */
subselect_engine *engine;
/* old engine if engine was changed */
@@ -53,13 +69,39 @@ protected:
/* cache of constant state */
bool const_item_cache;
+ bool inside_first_fix_fields;
+ bool done_first_fix_fields;
public:
- /*
- References from inside the subquery to the select that this predicate is
- in. References to parent selects not included.
+ /* A reference from inside subquery predicate to somewhere outside of it */
+ class Ref_to_outside : public Sql_alloc
+ {
+ public:
+ st_select_lex *select; /* Select where the reference is pointing to */
+ /*
+ What is being referred. This may be NULL when we're referring to an
+ aggregate function.
+ */
+ Item *item;
+ };
+ /*
+ References from within this subquery to somewhere outside of it (i.e. to
+ parent select, grandparent select, etc)
+ */
+ List<Ref_to_outside> upper_refs;
+ st_select_lex *parent_select;
+
+ /**
+ List of references on items subquery depends on (externally resolved);
+
+ @note We can't store direct links on Items because it could be
+ substituted with other item (for example for grouping).
+ */
+ List<Item*> depends_on;
+
+ /*
+ TRUE<=>Table Elimination has made it redundant to evaluate this select
+ (and so it is not part of QEP, etc)
*/
- List<Item> refers_to;
- int in_fix_fields;
bool eliminated;
/* changed engine indicator */
@@ -79,12 +121,12 @@ public:
virtual subs_type substype() { return UNKNOWN_SUBS; }
/*
- We need this method, because some compilers do not allow 'this'
- pointer in constructor initialization list, but we need pass pointer
- to subselect Item class to select_subselect classes constructor.
+ We need this method, because some compilers do not allow 'this'
+ pointer in constructor initialization list, but we need to pass a pointer
+ to subselect Item class to select_result_interceptor's constructor.
*/
virtual void init (st_select_lex *select_lex,
- select_subselect *result);
+ select_result_interceptor *result);
~Item_subselect();
void cleanup();
@@ -103,6 +145,9 @@ public:
return null_value;
}
bool fix_fields(THD *thd, Item **ref);
+ bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);
virtual bool exec();
virtual void fix_length_and_dec();
table_map used_tables() const;
@@ -149,8 +194,9 @@ public:
*/
st_select_lex* get_select_lex();
const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
+ virtual bool expr_cache_is_needed(THD *);
- friend class select_subselect;
+ friend class select_result_interceptor;
friend class Item_in_optimizer;
friend bool Item_field::fix_fields(THD *, Item **);
friend int Item_field::fix_outer_field(THD *, Field **, Item **);
@@ -158,6 +204,8 @@ public:
friend void mark_select_range_as_dependent(THD*,
st_select_lex*, st_select_lex*,
Field*, Item*, Item_ident*);
+ friend bool convert_join_subqueries_to_semijoins(JOIN *join);
+
};
/* single value subselect */
@@ -169,7 +217,8 @@ protected:
Item_cache *value, **row;
public:
Item_singlerow_subselect(st_select_lex *select_lex);
- Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
+ Item_singlerow_subselect() :Item_subselect(), value(0), row (0)
+ {}
void cleanup();
subs_type substype() { return SINGLEROW_SUBS; }
@@ -207,6 +256,8 @@ public:
*/
st_select_lex* invalidate_and_restore_select_lex();
+ Item* expr_cache_insert_transformer(uchar *thd_arg);
+
friend class select_singlerow_subselect;
};
@@ -254,20 +305,23 @@ public:
void fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
+ Item* expr_cache_insert_transformer(uchar *thd_arg);
+
friend class select_exists_subselect;
friend class subselect_uniquesubquery_engine;
friend class subselect_indexsubquery_engine;
};
-/*
- IN subselect: this represents "left_exr IN (SELECT ...)"
+/**
+ Representation of IN subquery predicates of the form
+ "left_expr IN (SELECT ...)".
+ @details
This class has:
- - (as a descendant of Item_subselect) a "subquery execution engine" which
- allows it to evaluate subqueries. (and this class participates in
- execution by having was_null variable where part of execution result
- is stored.
+ - A "subquery execution engine" (as a subclass of Item_subselect) that allows
+ it to evaluate subqueries. (and this class participates in execution by
+ having was_null variable where part of execution result is stored.
- Transformation methods (todo: more on this).
This class is not used directly, it is "wrapped" into Item_in_optimizer
@@ -276,8 +330,22 @@ public:
class Item_in_subselect :public Item_exists_subselect
{
-protected:
+public:
Item *left_expr;
+protected:
+ /*
+ Cache of the left operand of the subquery predicate. Allocated in the
+ runtime memory root, for each execution, thus need not be freed.
+ */
+ List<Cached_item> *left_expr_cache;
+ bool first_execution;
+ /*
+ Set to TRUE if at query execution time we determine that this item's
+ value is a constant during this execution. We need this member because
+ it is not possible to substitute 'this' with a constant item.
+ */
+ bool is_constant;
+
/*
expr & optimizer used in subselect rewriting to store Item for
all JOIN in UNION
@@ -286,10 +354,48 @@ protected:
Item_in_optimizer *optimizer;
bool was_null;
bool abort_on_null;
- bool transformed;
public:
/* Used to trigger on/off conditions that were pushed down to subselect */
bool *pushed_cond_guards;
+
+ /* Priority of this predicate in the convert-to-semi-join-nest process. */
+ int sj_convert_priority;
+ /*
+ Used by subquery optimizations to keep track about in which clause this
+ subquery predicate is located:
+ (TABLE_LIST*) 1 - the predicate is an AND-part of the WHERE
+ 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;
+ /*
+ Location of the subquery predicate. It is either
+ - pointer to join nest if the subquery predicate is in the ON expression
+ - (TABLE_LIST*)1 if the predicate is in the WHERE.
+ */
+ TABLE_LIST *expr_join_nest;
+ /*
+ Types of left_expr and subquery's select list allow to perform subquery
+ materialization. Currently, we set this to FALSE when it as well could
+ be TRUE. This is to be properly addressed with fix for BUG#36752.
+ */
+ bool types_allow_materialization;
+
+ /*
+ Same as above, but they also allow to scan the materialized table.
+ */
+ bool sjm_scan_allowed;
+
+ /* The method chosen to execute the IN predicate. */
+ enum enum_exec_method {
+ NOT_TRANSFORMED, /* No execution method was chosen for this IN. */
+ SEMI_JOIN, /* IN was converted to semi-join nest and should be removed. */
+ IN_TO_EXISTS, /* IN was converted to correlated EXISTS. */
+ MATERIALIZATION /* IN will be executed via subquery materialization. */
+ };
+ enum_exec_method exec_method;
bool *get_cond_guard(int i)
{
@@ -306,10 +412,11 @@ public:
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
Item_in_subselect()
- :Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
- pushed_cond_guards(NULL), upper_item(0)
+ :Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
+ is_constant(FALSE), optimizer(0), abort_on_null(0),
+ pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED), upper_item(0)
{}
-
+ void cleanup();
subs_type substype() { return IN_SUBS; }
void reset()
{
@@ -322,6 +429,10 @@ public:
trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
trans_res single_value_transformer(JOIN *join, Comp_creator *func);
trans_res row_value_transformer(JOIN * join);
+ trans_res single_value_in_to_exists_transformer(JOIN * join,
+ Comp_creator *func);
+ trans_res row_value_in_to_exists_transformer(JOIN * join);
+ virtual bool exec();
longlong val_int();
double val_real();
String *val_str(String*);
@@ -333,10 +444,26 @@ public:
bool test_limit(st_select_lex_unit *unit);
virtual void print(String *str, enum_query_type query_type);
bool fix_fields(THD *thd, Item **ref);
-
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void update_used_tables();
+ bool setup_engine();
+ bool init_left_expr_cache();
+ /* Inform 'this' that it was computed, and contains a valid result. */
+ void set_first_execution() { if (first_execution) first_execution= FALSE; }
+ bool is_expensive_processor(uchar *arg);
+ bool expr_cache_is_needed(THD *thd);
+
+ /*
+ Return the identifier that we could use to identify the subquery for the
+ user.
+ */
+ int get_identifier();
friend class Item_ref_null_helper;
friend class Item_is_not_null_test;
+ friend class Item_in_optimizer;
friend class subselect_indexsubquery_engine;
+ friend class subselect_hash_sj_engine;
+ friend class subselect_partial_match_engine;
};
@@ -361,7 +488,7 @@ public:
class subselect_engine: public Sql_alloc
{
protected:
- select_subselect *result; /* results storage class */
+ select_result_interceptor *result; /* results storage class */
THD *thd; /* pointer to current THD */
Item_subselect *item; /* item, that use this engine */
enum Item_result res_type; /* type of results */
@@ -369,14 +496,20 @@ protected:
bool maybe_null; /* may be null (first item in select) */
public:
- subselect_engine(Item_subselect *si, select_subselect *res)
- :thd(0)
+ enum enum_engine_type {ABSTRACT_ENGINE, SINGLE_SELECT_ENGINE,
+ UNION_ENGINE, UNIQUESUBQUERY_ENGINE,
+ INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE,
+ ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE};
+
+ subselect_engine(THD *thd_arg, Item_subselect *si,
+ select_result_interceptor *res)
{
result= res;
item= si;
res_type= STRING_RESULT;
res_field_type= MYSQL_TYPE_VAR_STRING;
maybe_null= 0;
+ set_thd(thd_arg);
}
virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup()= 0;
@@ -419,12 +552,14 @@ public:
virtual table_map upper_select_const_tables()= 0;
static table_map calc_const_tables(TABLE_LIST *);
virtual void print(String *str, enum_query_type query_type)= 0;
- virtual bool change_result(Item_subselect *si, select_subselect *result)= 0;
+ virtual bool change_result(Item_subselect *si,
+ select_result_interceptor *result)= 0;
virtual bool no_tables()= 0;
virtual bool is_executed() const { return FALSE; }
/* Check if subquery produced any rows during last query execution */
virtual bool no_rows() = 0;
-
+ virtual enum_engine_type engine_type() { return ABSTRACT_ENGINE; }
+ virtual int get_identifier() { DBUG_ASSERT(0); return 0; }
protected:
void set_row(List<Item> &item_list, Item_cache **row);
};
@@ -438,8 +573,8 @@ class subselect_single_select_engine: public subselect_engine
st_select_lex *select_lex; /* corresponding select_lex */
JOIN * join; /* corresponding JOIN structure */
public:
- subselect_single_select_engine(st_select_lex *select,
- select_subselect *result,
+ subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
+ select_result_interceptor *result,
Item_subselect *item);
void cleanup();
int prepare();
@@ -450,11 +585,16 @@ public:
void exclude();
table_map upper_select_const_tables();
virtual void print (String *str, enum_query_type query_type);
- bool change_result(Item_subselect *si, select_subselect *result);
+ bool change_result(Item_subselect *si, select_result_interceptor *result);
bool no_tables();
bool may_be_null();
bool is_executed() const { return executed; }
bool no_rows();
+ virtual enum_engine_type engine_type() { return SINGLE_SELECT_ENGINE; }
+ int get_identifier();
+
+ friend class subselect_hash_sj_engine;
+ friend class Item_in_subselect;
};
@@ -462,8 +602,8 @@ class subselect_union_engine: public subselect_engine
{
st_select_lex_unit *unit; /* corresponding unit structure */
public:
- subselect_union_engine(st_select_lex_unit *u,
- select_subselect *result,
+ subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
+ select_result_interceptor *result,
Item_subselect *item);
void cleanup();
int prepare();
@@ -474,10 +614,11 @@ public:
void exclude();
table_map upper_select_const_tables();
virtual void print (String *str, enum_query_type query_type);
- bool change_result(Item_subselect *si, select_subselect *result);
+ bool change_result(Item_subselect *si, select_result_interceptor *result);
bool no_tables();
bool is_executed() const;
bool no_rows();
+ virtual enum_engine_type engine_type() { return UNION_ENGINE; }
};
@@ -517,10 +658,8 @@ public:
// constructor can assign THD because it will be called after JOIN::prepare
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
Item_subselect *subs, Item *where)
- :subselect_engine(subs, 0), tab(tab_arg), cond(where)
- {
- set_thd(thd_arg);
- }
+ :subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where)
+ {}
~subselect_uniquesubquery_engine();
void cleanup();
int prepare();
@@ -531,11 +670,14 @@ public:
void exclude();
table_map upper_select_const_tables() { return 0; }
virtual void print (String *str, enum_query_type query_type);
- bool change_result(Item_subselect *si, select_subselect *result);
+ bool change_result(Item_subselect *si, select_result_interceptor *result);
bool no_tables();
+ int index_lookup(); /* TIMOUR: this method needs refactoring. */
int scan_table();
bool copy_ref_key();
+ int copy_ref_key_simple(); /* TIMOUR: this method needs refactoring. */
bool no_rows() { return empty_result_set; }
+ virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; }
};
@@ -585,6 +727,7 @@ public:
{}
int exec();
virtual void print (String *str, enum_query_type query_type);
+ virtual enum_engine_type engine_type() { return INDEXSUBQUERY_ENGINE; }
};
@@ -593,9 +736,446 @@ inline bool Item_subselect::is_evaluated() const
return engine->is_executed();
}
+
inline bool Item_subselect::is_uncacheable() const
{
return engine->uncacheable();
}
+/**
+ Compute an IN predicate via a hash semi-join. This class is responsible for
+ the materialization of the subquery, and the selection of the correct and
+ optimal execution method (e.g. direct index lookup, or partial matching) for
+ the IN predicate.
+*/
+
+class subselect_hash_sj_engine : public subselect_engine
+{
+protected:
+ /* The table into which the subquery is materialized. */
+ TABLE *tmp_table;
+ /* TRUE if the subquery was materialized into a temp table. */
+ bool is_materialized;
+ /*
+ The old engine already chosen at parse time and stored in permanent memory.
+ Through this member we can re-create and re-prepare materialize_join for
+ each execution of a prepared statement. We also reuse the functionality
+ of subselect_single_select_engine::[prepare | cols].
+ */
+ subselect_single_select_engine *materialize_engine;
+ /* The engine used to compute the IN predicate. */
+ subselect_engine *lookup_engine;
+ /*
+ QEP to execute the subquery and materialize its result into a
+ temporary table. Created during the first call to exec().
+ */
+ JOIN *materialize_join;
+
+ /* Keyparts of the only non-NULL composite index in a rowid merge. */
+ MY_BITMAP non_null_key_parts;
+ /* Keyparts of the single column indexes with NULL, one keypart per index. */
+ MY_BITMAP partial_match_key_parts;
+ uint count_partial_match_columns;
+ uint count_null_only_columns;
+ /*
+ A conjunction of all the equality condtions between all pairs of expressions
+ that are arguments of an IN predicate. We need these to post-filter some
+ IN results because index lookups sometimes match values that are actually
+ not equal to the search key in SQL terms.
+ */
+ Item_cond_and *semi_join_conds;
+ /* Possible execution strategies that can be used to compute hash semi-join.*/
+ enum exec_strategy {
+ UNDEFINED,
+ COMPLETE_MATCH, /* Use regular index lookups. */
+ PARTIAL_MATCH, /* Use some partial matching strategy. */
+ PARTIAL_MATCH_MERGE, /* Use partial matching through index merging. */
+ PARTIAL_MATCH_SCAN, /* Use partial matching through table scan. */
+ IMPOSSIBLE /* Subquery materialization is not applicable. */
+ };
+ /* The chosen execution strategy. Computed after materialization. */
+ exec_strategy strategy;
+protected:
+ exec_strategy get_strategy_using_schema();
+ exec_strategy get_strategy_using_data();
+ ulonglong rowid_merge_buff_size(bool has_non_null_key,
+ bool has_covering_null_row,
+ MY_BITMAP *partial_match_key_parts);
+ void choose_partial_match_strategy(bool has_non_null_key,
+ bool has_covering_null_row,
+ MY_BITMAP *partial_match_key_parts);
+ bool make_semi_join_conds();
+ subselect_uniquesubquery_engine* make_unique_engine();
+
+public:
+ subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
+ subselect_single_select_engine *old_engine)
+ :subselect_engine(thd, in_predicate, NULL), tmp_table(NULL),
+ is_materialized(FALSE), materialize_engine(old_engine), lookup_engine(NULL),
+ materialize_join(NULL), count_partial_match_columns(0),
+ count_null_only_columns(0), semi_join_conds(NULL), strategy(UNDEFINED)
+ {}
+ ~subselect_hash_sj_engine();
+
+ bool init_permanent(List<Item> *tmp_columns);
+ bool init_runtime();
+ void cleanup();
+ int prepare() { return 0; } /* Override virtual function in base class. */
+ int exec();
+ virtual void print(String *str, enum_query_type query_type);
+ uint cols()
+ {
+ return materialize_engine->cols();
+ }
+ uint8 uncacheable() { return materialize_engine->uncacheable(); }
+ table_map upper_select_const_tables() { return 0; }
+ bool no_rows() { return !tmp_table->file->stats.records; }
+ virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; }
+ /*
+ TODO: factor out all these methods in a base subselect_index_engine class
+ because all of them have dummy implementations and should never be called.
+ */
+ void fix_length_and_dec(Item_cache** row);//=>base class
+ void exclude(); //=>base class
+ //=>base class
+ bool change_result(Item_subselect *si, select_result_interceptor *result);
+ bool no_tables();//=>base class
+};
+
+
+/*
+ Distinguish the type od (0-based) row numbers from the type of the index into
+ an array of row numbers.
+*/
+typedef ha_rows rownum_t;
+
+
+/*
+ An Ordered_key is an in-memory table index that allows O(log(N)) time
+ lookups of a multi-part key.
+
+ If the index is over a single column, then this column may contain NULLs, and
+ the NULLs are stored and tested separately for NULL in O(1) via is_null().
+ Multi-part indexes assume that the indexed columns do not contain NULLs.
+
+ TODO:
+ = Due to the unnatural assymetry between single and multi-part indexes, it
+ makes sense to somehow refactor or extend the class.
+
+ = This class can be refactored into a base abstract interface, and two
+ subclasses:
+ - one to represent single-column indexes, and
+ - another to represent multi-column indexes.
+ Such separation would allow slightly more efficient implementation of
+ the single-column indexes.
+ = The current design requires such indexes to be fully recreated for each
+ PS (re)execution, however most of the comprising objects can be reused.
+*/
+
+class Ordered_key : public Sql_alloc
+{
+protected:
+ /*
+ Index of the key in an array of keys. This index allows to
+ construct (sub)sets of keys represented by bitmaps.
+ */
+ uint keyid;
+ /* The table being indexed. */
+ TABLE *tbl;
+ /* The columns being indexed. */
+ Item_field **key_columns;
+ /* Number of elements in 'key_columns' (number of key parts). */
+ uint key_column_count;
+ /*
+ An expression, or sequence of expressions that forms the search key.
+ The search key is a sequence when it is Item_row. Each element of the
+ sequence is accessible via Item::element_index(int i).
+ */
+ Item *search_key;
+
+/* Value index related members. */
+ /*
+ The actual value index, consists of a sorted sequence of row numbers.
+ */
+ rownum_t *key_buff;
+ /* Number of elements in key_buff. */
+ ha_rows key_buff_elements;
+ /* Current element in 'key_buff'. */
+ ha_rows cur_key_idx;
+ /*
+ Mapping from row numbers to row ids. The element row_num_to_rowid[i]
+ contains a buffer with the rowid for the row numbered 'i'.
+ The memory for this member is not maintanined by this class because
+ all Ordered_key indexes of the same table share the same mapping.
+ */
+ uchar *row_num_to_rowid;
+ /*
+ A sequence of predicates to compare the search key with the corresponding
+ columns of a table row from the index.
+ */
+ Item_func_lt **compare_pred;
+
+/* Null index related members. */
+ MY_BITMAP null_key;
+ /* 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;
+ /* The row number that contains the last NULL in a column. */
+ ha_rows max_null_row;
+
+protected:
+ bool alloc_keys_buffers();
+ /*
+ Quick sort comparison function that compares two rows of the same table
+ indentfied with their row numbers.
+ */
+ int cmp_keys_by_row_data(rownum_t a, rownum_t b);
+ static int cmp_keys_by_row_data_and_rownum(Ordered_key *key,
+ rownum_t* a, rownum_t* b);
+
+ int cmp_key_with_search_key(rownum_t row_num);
+
+public:
+ Ordered_key(uint keyid_arg, TABLE *tbl_arg,
+ Item *search_key_arg, ha_rows null_count_arg,
+ ha_rows min_null_row_arg, ha_rows max_null_row_arg,
+ uchar *row_num_to_rowid_arg);
+ ~Ordered_key();
+ void cleanup();
+ /* Initialize a multi-column index. */
+ bool init(MY_BITMAP *columns_to_index);
+ /* Initialize a single-column index. */
+ bool init(int col_idx);
+
+ uint get_column_count() { return key_column_count; }
+ uint get_keyid() { return keyid; }
+ uint get_field_idx(uint i)
+ {
+ DBUG_ASSERT(i < key_column_count);
+ return key_columns[i]->field->field_index;
+ }
+ /*
+ Get the search key element that corresponds to the i-th key part of this
+ index.
+ */
+ Item *get_search_key(uint i)
+ {
+ return search_key->element_index(key_columns[i]->field->field_index);
+ }
+ void add_key(rownum_t row_num)
+ {
+ /* The caller must know how many elements to add. */
+ DBUG_ASSERT(key_buff_elements && cur_key_idx < key_buff_elements);
+ key_buff[cur_key_idx]= row_num;
+ ++cur_key_idx;
+ }
+
+ void sort_keys();
+ double null_selectivity();
+
+ /*
+ Position the current element at the first row that matches the key.
+ The key itself is propagated by evaluating the current value(s) of
+ this->search_key.
+ */
+ bool lookup();
+ /* Move the current index cursor to the first key. */
+ void first()
+ {
+ DBUG_ASSERT(key_buff_elements);
+ cur_key_idx= 0;
+ }
+ /* TODO */
+ bool next_same();
+ /* Move the current index cursor to the next key. */
+ bool next()
+ {
+ DBUG_ASSERT(key_buff_elements);
+ if (cur_key_idx < key_buff_elements - 1)
+ {
+ ++cur_key_idx;
+ return TRUE;
+ }
+ return FALSE;
+ };
+ /* Return the current index element. */
+ rownum_t current()
+ {
+ DBUG_ASSERT(key_buff_elements && cur_key_idx < key_buff_elements);
+ return key_buff[cur_key_idx];
+ }
+
+ void set_null(rownum_t row_num)
+ {
+ bitmap_set_bit(&null_key, row_num);
+ }
+ bool is_null(rownum_t row_num)
+ {
+ /*
+ Indexes consisting of only NULLs do not have a bitmap buffer at all.
+ Their only initialized member is 'n_bits', which is equal to the number
+ of temp table rows.
+ */
+ if (null_count == tbl->file->stats.records)
+ {
+ DBUG_ASSERT(tbl->file->stats.records == null_key.n_bits);
+ return TRUE;
+ }
+ if (row_num > max_null_row || row_num < min_null_row)
+ return FALSE;
+ return bitmap_is_set(&null_key, row_num);
+ }
+ void print(String *str);
+};
+
+
+class subselect_partial_match_engine : public subselect_engine
+{
+protected:
+ /* The temporary table that contains a materialized subquery. */
+ TABLE *tmp_table;
+ /*
+ The engine used to check whether an IN predicate is TRUE or not. If not
+ TRUE, then subselect_rowid_merge_engine further distinguishes between
+ FALSE and UNKNOWN.
+ */
+ subselect_uniquesubquery_engine *lookup_engine;
+ /* A list of equalities between each pair of IN operands. */
+ List<Item> *equi_join_conds;
+ /*
+ If there is a row, such that all its NULL-able components are NULL, this
+ member is set to the number of covered columns. If there is no covering
+ row, then this is 0.
+ */
+ uint covering_null_row_width;
+protected:
+ virtual bool partial_match()= 0;
+public:
+ subselect_partial_match_engine(THD *thd_arg,
+ subselect_uniquesubquery_engine *engine_arg,
+ TABLE *tmp_table_arg, Item_subselect *item_arg,
+ select_result_interceptor *result_arg,
+ List<Item> *equi_join_conds_arg,
+ uint covering_null_row_width_arg);
+ int prepare() { return 0; }
+ int exec();
+ void fix_length_and_dec(Item_cache**) {}
+ uint cols() { /* TODO: what is the correct value? */ return 1; }
+ uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
+ void exclude() {}
+ table_map upper_select_const_tables() { return 0; }
+ bool change_result(Item_subselect*, select_result_interceptor*)
+ { DBUG_ASSERT(FALSE); return false; }
+ bool no_tables() { return false; }
+ bool no_rows()
+ {
+ /*
+ TODO: It is completely unclear what is the semantics of this
+ method. The current result is computed so that the call to no_rows()
+ from Item_in_optimizer::val_int() sets Item_in_optimizer::null_value
+ correctly.
+ */
+ return !(((Item_in_subselect *) item)->null_value);
+ }
+ void print(String*, enum_query_type);
+
+ friend void subselect_hash_sj_engine::cleanup();
+};
+
+
+class subselect_rowid_merge_engine: public subselect_partial_match_engine
+{
+protected:
+ /*
+ Mapping from row numbers to row ids. The rowids are stored sequentially
+ in the array - rowid[i] is located in row_num_to_rowid + i * rowid_length.
+ */
+ uchar *row_num_to_rowid;
+ /*
+ A subset of all the keys for which there is a match for the same row.
+ Used during execution. Computed for each outer reference
+ */
+ MY_BITMAP matching_keys;
+ /*
+ The columns of the outer reference that are NULL. Computed for each
+ outer reference.
+ */
+ MY_BITMAP matching_outer_cols;
+ /*
+ Columns that consist of only NULLs. Such columns match any value.
+ Computed once per query execution.
+ */
+ MY_BITMAP null_only_columns;
+ /*
+ Indexes of row numbers, sorted by <column_value, row_number>. If an
+ index may contain NULLs, the NULLs are stored efficiently in a bitmap.
+
+ The indexes are sorted by the selectivity of their NULL sub-indexes, the
+ one with the fewer NULLs is first. Thus, if there is any index on
+ non-NULL columns, it is contained in keys[0].
+ */
+ Ordered_key **merge_keys;
+ /* The number of elements in keys. */
+ uint keys_count;
+ /*
+ An index on all non-NULL columns of 'tmp_table'. The index has the
+ logical form: <[v_i1 | ... | v_ik], rownum>. It allows to find the row
+ number where the columns c_i1,...,c1_k contain the values v_i1,...,v_ik.
+ If such an index exists, it is always the first element of 'keys'.
+ */
+ Ordered_key *non_null_key;
+ /*
+ Priority queue of Ordered_key indexes, one per NULLable column.
+ This queue is used by the partial match algorithm in method exec().
+ */
+ QUEUE pq;
+protected:
+ /*
+ Comparison function to compare keys in order of decreasing bitmap
+ selectivity.
+ */
+ static int cmp_keys_by_null_selectivity(Ordered_key **k1, Ordered_key **k2);
+ /*
+ Comparison function used by the priority queue pq, the 'smaller' key
+ is the one with the smaller current row number.
+ */
+ static int cmp_keys_by_cur_rownum(void *arg, uchar *k1, uchar *k2);
+
+ bool test_null_row(rownum_t row_num);
+ bool partial_match();
+public:
+ subselect_rowid_merge_engine(THD *thd_arg,
+ subselect_uniquesubquery_engine *engine_arg,
+ TABLE *tmp_table_arg, uint keys_count_arg,
+ uint covering_null_row_width_arg,
+ Item_subselect *item_arg,
+ select_result_interceptor *result_arg,
+ List<Item> *equi_join_conds_arg)
+ :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
+ item_arg, result_arg, equi_join_conds_arg,
+ covering_null_row_width_arg),
+ keys_count(keys_count_arg), non_null_key(NULL)
+ {}
+ ~subselect_rowid_merge_engine();
+ bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);
+ void cleanup();
+ virtual enum_engine_type engine_type() { return ROWID_MERGE_ENGINE; }
+};
+
+
+class subselect_table_scan_engine: public subselect_partial_match_engine
+{
+protected:
+ bool partial_match();
+public:
+ subselect_table_scan_engine(THD *thd_arg,
+ subselect_uniquesubquery_engine *engine_arg,
+ TABLE *tmp_table_arg, Item_subselect *item_arg,
+ select_result_interceptor *result_arg,
+ List<Item> *equi_join_conds_arg,
+ uint covering_null_row_width_arg);
+ 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 86d1b693f28..f5fc52828c7 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -319,6 +319,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
if (aggr_level >= 0)
{
ref_by= ref;
+ thd->lex->current_select->register_dependency_item(aggr_sel, ref);
/* Add the object to the list of registered objects assigned to aggr_sel */
if (!aggr_sel->inner_sum_func_list)
next= this;
@@ -350,7 +351,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
sl= sl->master_unit()->outer_select() )
sl->master_unit()->item->with_sum_func= 1;
}
- thd->lex->current_select->mark_as_dependent(aggr_sel, NULL);
+ thd->lex->current_select->mark_as_dependent(thd, aggr_sel, NULL);
return FALSE;
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index b5516792676..46e5ae76ab1 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1274,8 +1274,13 @@ public:
void make_unique();
double val_real()
{
- String *res; res=val_str(&str_value);
- return res ? my_atof(res->c_ptr()) : 0.0;
+ int error;
+ const char *end;
+ String *res;
+ if (!(res= val_str(&str_value)))
+ return 0.0;
+ end= res->ptr() + res->length();
+ return (my_strtod(res->ptr(), (char**) &end, &error));
}
longlong val_int()
{
diff --git a/sql/key.cc b/sql/key.cc
index 89423e5280e..0de1d1fd642 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -113,13 +113,24 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
if (key_length == 0)
key_length= key_info->key_length;
- for (key_part= key_info->key_part; (int) key_length > 0; key_part++)
+ for (key_part= key_info->key_part;
+ (int) key_length > 0;
+ key_part++, to_key+= length, key_length-= length)
{
if (key_part->null_bit)
{
*to_key++= test(from_record[key_part->null_offset] &
key_part->null_bit);
key_length--;
+ if (to_key[-1])
+ {
+ /*
+ Don't copy data for null values
+ The -1 below is to subtract the null byte which is already handled
+ */
+ length= min(key_length, (uint) key_part->store_length-1);
+ continue;
+ }
}
if (key_part->key_part_flag & HA_BLOB_PART ||
key_part->key_part_flag & HA_VAR_LENGTH_PART)
@@ -138,8 +149,6 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
if (bytes < length)
cs->cset->fill(cs, (char*) to_key + bytes, length - bytes, ' ');
}
- to_key+= length;
- key_length-= length;
}
}
@@ -166,16 +175,28 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
{
key_length= key_info->key_length;
}
- for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++)
+ for (key_part= key_info->key_part ;
+ (int) key_length > 0 ;
+ key_part++, from_key+= length, key_length-= length)
{
uchar used_uneven_bits= 0;
if (key_part->null_bit)
{
- if (*from_key++)
+ bool null_value;
+ if ((null_value= *from_key++))
to_record[key_part->null_offset]|= key_part->null_bit;
else
to_record[key_part->null_offset]&= ~key_part->null_bit;
key_length--;
+ if (null_value)
+ {
+ /*
+ Don't copy data for null bytes
+ The -1 below is to subtract the null byte which is already handled
+ */
+ length= min(key_length, (uint) key_part->store_length-1);
+ continue;
+ }
}
if (key_part->type == HA_KEYTYPE_BIT)
{
@@ -229,8 +250,6 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
memcpy(to_record + key_part->offset, from_key + used_uneven_bits
, (size_t) length - used_uneven_bits);
}
- from_key+= length;
- key_length-= length;
}
}
@@ -548,3 +567,302 @@ next_loop:
} while (key_info); /* no more keys to test */
DBUG_RETURN(0);
}
+
+
+/*
+ Compare two key tuples.
+
+ @brief
+ Compare two key tuples, i.e. two key values in KeyTupleFormat.
+
+ @param part KEY_PART_INFO with key description
+ @param key1 First key to compare
+ @param key2 Second key to compare
+ @param tuple_length Length of key1 (and key2, they are the same) in bytes.
+
+ @return
+ @retval 0 key1 == key2
+ @retval -1 key1 < key2
+ @retval +1 key1 > key2
+*/
+
+int key_tuple_cmp(KEY_PART_INFO *part, uchar *key1, uchar *key2,
+ uint tuple_length)
+{
+ uchar *key1_end= key1 + tuple_length;
+ int len;
+ int res;
+ LINT_INIT(len);
+ for (;key1 < key1_end; key1 += len, key2 += len, part++)
+ {
+ len= part->store_length;
+ if (part->null_bit)
+ {
+ if (*key1) // key1 == NULL
+ {
+ if (!*key2) // key1(NULL) < key2(notNULL)
+ return -1;
+ continue;
+ }
+ else if (*key2) // key1(notNULL) > key2 (NULL)
+ return 1;
+ /* Step over the NULL bytes for key_cmp() call */
+ key1++;
+ key2++;
+ len--;
+ }
+ if ((res= part->field->key_cmp(key1, key2)))
+ return res;
+ }
+ return 0;
+}
+
+
+/**
+ Get hash value for the key from a key buffer
+
+ @param key_info the key descriptor
+ @param used_key_part number of key parts used for the key
+ @param key pointer to the buffer with the key value
+
+ @datails
+ When hashing we should take special care only of:
+ 1. NULLs (and keyparts which can be null so one byte reserved for it);
+ 2. Strings for which we have to take into account their collations
+ and the values of their lengths in the prefixes.
+
+ @return hash value calculated for the key
+*/
+
+ulong key_hashnr(KEY *key_info, uint used_key_parts, const uchar *key)
+{
+ ulong nr=1, nr2=4;
+ KEY_PART_INFO *key_part= key_info->key_part;
+ KEY_PART_INFO *end_key_part= key_part + used_key_parts;
+
+ for (; key_part < end_key_part; key_part++)
+ {
+ uchar *pos= (uchar*)key;
+ CHARSET_INFO *cs;
+ uint length, pack_length;
+ bool is_string= TRUE;
+ LINT_INIT(cs);
+ key+= key_part->length;
+ if (key_part->null_bit)
+ {
+ key++; /* Skip null byte */
+ if (*pos) /* Found null */
+ {
+ nr^= (nr << 1) | 1;
+ /* Add key pack length to key for VARCHAR segments */
+ switch (key_part->type) {
+ case HA_KEYTYPE_VARTEXT1:
+ case HA_KEYTYPE_VARBINARY1:
+ key++;
+ break;
+ case HA_KEYTYPE_VARTEXT2:
+ case HA_KEYTYPE_VARBINARY2:
+ key+= 2;
+ break;
+ default:
+ ;
+ }
+ continue;
+ }
+ pos++; /* Skip null byte */
+ }
+ /* If it is string set parameters of the string */
+ switch (key_part->type) {
+ case HA_KEYTYPE_TEXT:
+ cs= key_part->field->charset();
+ length= key_part->length;
+ pack_length= 0;
+ break;
+ case HA_KEYTYPE_BINARY :
+ cs= &my_charset_bin;
+ length= key_part->length;
+ pack_length= 0;
+ break;
+ case HA_KEYTYPE_VARTEXT1:
+ cs= key_part->field->charset();
+ length= (uint)(pos[0]);
+ pack_length= 1;
+ break;
+ case HA_KEYTYPE_VARBINARY1:
+ cs= &my_charset_bin;
+ length= (uint)(pos[0]);
+ pack_length= 1;
+ break;
+ case HA_KEYTYPE_VARTEXT2:
+ cs= key_part->field->charset();
+ length= uint2korr(pos);
+ pack_length= 2;
+ break;
+ case HA_KEYTYPE_VARBINARY2:
+ cs= &my_charset_bin;
+ length= uint2korr(pos);
+ pack_length= 2;
+ break;
+ default:
+ is_string= FALSE;
+ }
+
+ if (is_string)
+ {
+ if (cs->mbmaxlen > 1)
+ {
+ uint char_length= my_charpos(cs, pos + pack_length,
+ pos + pack_length + length,
+ length / cs->mbmaxlen);
+ set_if_smaller(length, char_length);
+ }
+ cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
+ key+= pack_length;
+ }
+ else
+ {
+ for (; pos < (uchar*)key ; pos++)
+ {
+ nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
+ nr2+=3;
+ }
+ }
+ }
+ DBUG_PRINT("exit", ("hash: %lx", nr));
+ return(nr);
+}
+
+
+/**
+ Check whether two keys in the key buffers are equal
+
+ @param key_info the key descriptor
+ @param used_key_part number of key parts used for the keys
+ @param key1 pointer to the buffer with the first key
+ @param key2 pointer to the buffer with the second key
+
+ @detail See details of key_hashnr().
+
+ @retval TRUE keys in the buffers are NOT equal
+ @retval FALSE keys in the buffers are equal
+*/
+
+bool key_buf_cmp(KEY *key_info, uint used_key_parts,
+ const uchar *key1, const uchar *key2)
+{
+ KEY_PART_INFO *key_part= key_info->key_part;
+ KEY_PART_INFO *end_key_part= key_part + used_key_parts;
+
+ for (; key_part < end_key_part; key_part++)
+ {
+ uchar *pos1= (uchar*)key1;
+ uchar *pos2= (uchar*)key2;
+ CHARSET_INFO *cs;
+ uint length1, length2, pack_length;
+ bool is_string= TRUE;
+ LINT_INIT(cs);
+ key1+= key_part->length;
+ key2+= key_part->length;
+ if (key_part->null_bit)
+ {
+ key1++; key2++; /* Skip null byte */
+ if (*pos1 && *pos2) /* Both are null */
+ {
+ /* Add key pack length to key for VARCHAR segments */
+ switch (key_part->type) {
+ case HA_KEYTYPE_VARTEXT1:
+ case HA_KEYTYPE_VARBINARY1:
+ key1++; key2++;
+ break;
+ case HA_KEYTYPE_VARTEXT2:
+ case HA_KEYTYPE_VARBINARY2:
+ key1+= 2; key2+= 2;
+ break;
+ default:
+ ;
+ }
+ continue;
+ }
+ if (*pos1 != *pos2)
+ return FALSE;
+ pos1++; pos2++;
+ }
+
+ /* If it is string set parameters of the string */
+ switch (key_part->type) {
+ case HA_KEYTYPE_TEXT:
+ cs= key_part->field->charset();
+ length1= length2= key_part->length;
+ pack_length= 0;
+ break;
+ case HA_KEYTYPE_BINARY :
+ cs= &my_charset_bin;
+ length1= length2= key_part->length;
+ pack_length= 0;
+ break;
+ case HA_KEYTYPE_VARTEXT1:
+ cs= key_part->field->charset();
+ length1= (uint)(pos1[0]);
+ length2= (uint)(pos2[0]);
+ pack_length= 1;
+ break;
+ case HA_KEYTYPE_VARBINARY1:
+ cs= &my_charset_bin;
+ length1= (uint)(pos1[0]);
+ length2= (uint)(pos2[0]);
+ pack_length= 1;
+ break;
+ case HA_KEYTYPE_VARTEXT2:
+ cs= key_part->field->charset();
+ length1= uint2korr(pos1);
+ length2= uint2korr(pos2);
+ pack_length= 2;
+ break;
+ case HA_KEYTYPE_VARBINARY2:
+ cs= &my_charset_bin;
+ length1= uint2korr(pos1);
+ length2= uint2korr(pos2);
+ pack_length= 2;
+ break;
+ default:
+ is_string= FALSE;
+ }
+
+ if (is_string)
+ {
+ /*
+ Compare the strings taking into account length in characters
+ and collation
+ */
+ uint byte_len1= length1, byte_len2= length2;
+ if (cs->mbmaxlen > 1)
+ {
+ uint char_length1= my_charpos(cs, pos1 + pack_length,
+ pos1 + pack_length + length1,
+ length1 / cs->mbmaxlen);
+ uint char_length2= my_charpos(cs, pos2 + pack_length,
+ pos2 + pack_length + length2,
+ length2 / cs->mbmaxlen);
+ set_if_smaller(length1, char_length1);
+ set_if_smaller(length2, char_length2);
+ }
+ if (length1 != length2 ||
+ cs->coll->strnncollsp(cs,
+ pos1 + pack_length, byte_len1,
+ pos2 + pack_length, byte_len2,
+ 1))
+ return TRUE;
+ key1+= pack_length; key2+= pack_length;
+ }
+ else
+ {
+ /* it is OK to compare non-string byte per byte */
+ for (; pos1 < (uchar*)key1 ; pos1++, pos2++)
+ {
+ if (pos1[0] != pos2[0])
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
diff --git a/sql/lock.cc b/sql/lock.cc
index e5ea85e7ce7..4cab521fada 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -84,41 +84,10 @@
extern HASH open_cache;
-/* flags for get_lock_data */
-#define GET_LOCK_UNLOCK 1
-#define GET_LOCK_STORE_LOCKS 2
-
-static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
- uint flags, TABLE **write_locked);
-static void reset_lock_data(MYSQL_LOCK *sql_lock);
static int lock_external(THD *thd, TABLE **table,uint count);
static int unlock_external(THD *thd, TABLE **table,uint count);
static void print_lock_error(int error, const char *);
-/*
- Lock tables.
-
- SYNOPSIS
- mysql_lock_tables()
- thd The current thread.
- tables An array of pointers to the tables to lock.
- count The number of tables to lock.
- flags Options:
- MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
- MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY
- MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables.
- MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered
- or dropped tables by itself,
- mysql_lock_tables() should
- notify upper level and rely
- on caller doing this.
- need_reopen Out parameter, TRUE if some tables were altered
- or deleted and should be reopened by caller.
-
- RETURN
- A lock structure pointer on success.
- NULL on error or if some tables should be reopen.
-*/
/* Map the return value of thr_lock to an error from errmsg.txt */
static int thr_lock_errno_to_mysql[]=
@@ -132,6 +101,7 @@ static int thr_lock_errno_to_mysql[]=
@param flags Lock flags
@return 0 if all the check passed, non zero if a check failed.
*/
+
int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
{
bool log_table_write_query;
@@ -194,81 +164,118 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
DBUG_RETURN(0);
}
+
+/*
+ Lock tables.
+
+ SYNOPSIS
+ mysql_lock_tables()
+ thd The current thread.
+ tables An array of pointers to the tables to lock.
+ count The number of tables to lock.
+ flags Options:
+ MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
+ MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY
+ MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables.
+ MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered
+ or dropped tables by itself,
+ mysql_lock_tables() should
+ notify upper level and rely
+ on caller doing this.
+ need_reopen Out parameter, TRUE if some tables were altered
+ or deleted and should be reopened by caller.
+
+ RETURN
+ A lock structure pointer on success.
+ NULL on error or if some tables should be reopen.
+*/
+
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
uint flags, bool *need_reopen)
{
- MYSQL_LOCK *sql_lock;
TABLE *write_lock_used;
- int rc;
-
- DBUG_ENTER("mysql_lock_tables");
+ MYSQL_LOCK *sql_lock;
+ DBUG_ENTER("mysql_lock_tables(tables)");
*need_reopen= FALSE;
-
if (mysql_lock_tables_check(thd, tables, count, flags))
- DBUG_RETURN (NULL);
+ DBUG_RETURN(NULL);
- for (;;)
+ if (!(sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
+ &write_lock_used)) ||
+ ! sql_lock->table_count)
+ DBUG_RETURN(sql_lock);
+
+ if (mysql_lock_tables(thd, sql_lock, write_lock_used != 0, flags,
+ need_reopen))
{
- if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
- &write_lock_used)) ||
- ! sql_lock->table_count)
- break;
+ /* Clear the lock type of all lock data to avoid reusage. */
+ reset_lock_data(sql_lock, 1);
+ my_free(sql_lock, MYF(0));
+ sql_lock= 0;
+ }
+ DBUG_RETURN(sql_lock);
+}
+
+
+/**
+ Lock a table based on a MYSQL_LOCK structure.
- if (global_read_lock && write_lock_used &&
- ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
+ mysql_lock_tables()
+
+ @param thd The current thread.
+ @param sql_lock Tables that should be locked
+ @param write_lock_used 1 if any of the tables are write locked
+ @param flags See mysql_lock_tables()
+ @param need_reopen Out parameter, TRUE if some tables were altered
+ or deleted and should be reopened by caller.
+
+ @return 0 ok
+ @return 1 error
+*/
+
+bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock,
+ bool write_lock_used,
+ uint flags, bool *need_reopen)
+{
+ int rc;
+ bool error= 1;
+ DBUG_ENTER("mysql_lock_tables(sql_lock)");
+
+ *need_reopen= FALSE;
+ for (;;)
+ {
+ if (write_lock_used && !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
{
- /*
- Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
- Wait until the lock is gone
- */
- if (wait_if_global_read_lock(thd, 1, 1))
+ if (global_read_lock)
{
- /* Clear the lock type of all lock data to avoid reusage. */
- reset_lock_data(sql_lock);
- my_free((uchar*) sql_lock,MYF(0));
- sql_lock=0;
- break;
+ /*
+ Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
+ Wait until the lock is gone
+ */
+ if (wait_if_global_read_lock(thd, 1, 1))
+ break;
+ if (thd->version != refresh_version)
+ goto retry;
}
- if (thd->version != refresh_version)
+
+ if (opt_readonly &&
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ !thd->slave_thread)
{
- /* Clear the lock type of all lock data to avoid reusage. */
- reset_lock_data(sql_lock);
- my_free((uchar*) sql_lock,MYF(0));
- goto retry;
+ /*
+ Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
+ We do not wait for READ_ONLY=0, and fail.
+ */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+ break;
}
}
- if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
- write_lock_used &&
- opt_readonly &&
- !(thd->security_ctx->master_access & SUPER_ACL) &&
- !thd->slave_thread)
- {
- /*
- Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
- We do not wait for READ_ONLY=0, and fail.
- */
- reset_lock_data(sql_lock);
- my_free((uchar*) sql_lock, MYF(0));
- sql_lock=0;
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
- break;
- }
-
thd_proc_info(thd, "System lock");
- DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
if (lock_external(thd, sql_lock->table, sql_lock->table_count))
- {
- /* Clear the lock type of all lock data to avoid reusage. */
- reset_lock_data(sql_lock);
- my_free((uchar*) sql_lock,MYF(0));
- sql_lock=0;
break;
- }
thd_proc_info(thd, "Table lock");
- DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
- thd->locked=1;
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
sql_lock->lock_count * sizeof(*sql_lock->locks));
@@ -277,70 +284,66 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
sql_lock->lock_count,
sql_lock->lock_count,
thd->lock_id)];
- if (rc > 1) /* a timeout or a deadlock */
+ if (rc) /* Locking failed */
{
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
- my_error(rc, MYF(0));
- my_free((uchar*) sql_lock,MYF(0));
- sql_lock= 0;
- break;
- }
- else if (rc == 1) /* aborted */
- {
- /*
- reset_lock_data is required here. If thr_multi_lock fails it
- resets lock type for tables, which were locked before (and
- including) one that caused error. Lock type for other tables
- preserved.
- */
- reset_lock_data(sql_lock);
- thd->some_tables_deleted=1; // Try again
- sql_lock->lock_count= 0; // Locks are already freed
+ if (rc > 1)
+ {
+ /* a timeout or a deadlock */
+ my_error(rc, MYF(0));
+ break;
+ }
+ /* We where aborted and should try again from upper level*/
+ thd->some_tables_deleted= 1;
}
- else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
+ else
{
/*
- Thread was killed or lock aborted. Let upper level close all
- used tables and retry or give error.
+ Lock worked. Now check that nothing happend while we where waiting
+ to get the lock that would require us to free it.
*/
- thd->locked=0;
- break;
- }
- else if (!thd->open_tables)
- {
- // Only using temporary tables, no need to unlock
- thd->some_tables_deleted=0;
- thd->locked=0;
- break;
+ error= 0;
+ if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
+ {
+ /*
+ Table was not signaled for deletion or we don't care if it was.
+ Return with table as locked.
+ */
+ break;
+ }
+ else if (!thd->open_tables && !(flags & MYSQL_LOCK_NOT_TEMPORARY))
+ {
+ /*
+ Only using temporary tables, no need to unlock.
+ We need the flag as open_tables is not enough to distingush if
+ we are only using temporary tables for tables used trough
+ the HANDLER interface.
+
+ We reset some_tables_deleted as it doesn't make sense to have this
+ one when we are only using temporary tables.
+ */
+ thd->some_tables_deleted=0;
+ break;
+ }
+ /* some table was altered or deleted. reopen tables marked deleted */
+ error= 1;
+ mysql_unlock_tables(thd, sql_lock, 0);
}
- thd_proc_info(thd, 0);
- /* some table was altered or deleted. reopen tables marked deleted */
- mysql_unlock_tables(thd,sql_lock);
- thd->locked=0;
retry:
- sql_lock=0;
if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
{
*need_reopen= TRUE;
break;
}
if (wait_for_tables(thd))
- break; // Couldn't open tables
- }
- thd_proc_info(thd, 0);
- if (thd->killed)
- {
- thd->send_kill_message();
- if (sql_lock)
- {
- mysql_unlock_tables(thd,sql_lock);
- sql_lock=0;
- }
+ break; // Couldn't open tables
+ reset_lock_data(sql_lock, 0); // Set org locks and retry
}
+ thd_proc_info(thd, 0);
thd->set_time_after_lock();
- DBUG_RETURN (sql_lock);
+ DBUG_RETURN(error);
}
@@ -380,15 +383,15 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
DBUG_RETURN(0);
}
-
-void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
+void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
{
DBUG_ENTER("mysql_unlock_tables");
if (sql_lock->table_count)
VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
if (sql_lock->lock_count)
thr_multi_unlock(sql_lock->locks,sql_lock->lock_count, 0);
- my_free((uchar*) sql_lock,MYF(0));
+ if (free_lock)
+ my_free((uchar*) sql_lock,MYF(0));
DBUG_VOID_RETURN;
}
@@ -847,12 +850,12 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
*/
-static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
- uint flags, TABLE **write_lock_used)
+MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
+ uint flags, TABLE **write_lock_used)
{
uint i,tables,lock_count;
MYSQL_LOCK *sql_lock;
- THR_LOCK_DATA **locks, **locks_buf, **locks_start;
+ THR_LOCK_DATA **locks, **locks_buf;
TABLE **to, **table_buf;
DBUG_ENTER("get_lock_data");
@@ -891,7 +894,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{
TABLE *table;
enum thr_lock_type lock_type;
-
+ THR_LOCK_DATA **locks_start;
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
continue;
lock_type= table->reginfo.lock_type;
@@ -901,15 +904,14 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*write_lock_used=table;
if (table->db_stat & HA_READ_ONLY)
{
- my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias);
+ my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias.c_ptr());
/* Clear the lock type of the lock data that are stored already. */
sql_lock->lock_count= (uint) (locks - sql_lock->locks);
- reset_lock_data(sql_lock);
+ reset_lock_data(sql_lock, 1);
my_free((uchar*) sql_lock,MYF(0));
DBUG_RETURN(0);
}
}
- THR_LOCK_DATA **org_locks = locks;
locks_start= locks;
locks= table->file->store_lock(thd, locks,
(flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
@@ -922,8 +924,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
}
*to++= table;
if (locks)
- for ( ; org_locks != locks ; org_locks++)
- (*org_locks)->debug_print_param= (void *) table;
+ {
+ for ( ; locks_start != locks ; locks_start++)
+ {
+ (*locks_start)->debug_print_param= (void *) table;
+ (*locks_start)->org_type= (*locks_start)->type;
+ }
+ }
}
/*
We do not use 'tables', because there are cases where store_lock()
@@ -964,10 +971,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
Clear the lock type of all lock data. This ensures that the next
lock request will set its lock type properly.
- @param sql_lock The MySQL lock.
+ @param sql_lock The MySQL lock.
+ @param unlock If set, then set lock type to TL_UNLOCK,
+ otherwise set to original lock type from
+ get_store_lock().
*/
-static void reset_lock_data(MYSQL_LOCK *sql_lock)
+void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock)
{
THR_LOCK_DATA **ldata;
THR_LOCK_DATA **ldata_end;
@@ -975,10 +985,7 @@ static void reset_lock_data(MYSQL_LOCK *sql_lock)
for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count;
ldata < ldata_end;
ldata++)
- {
- /* Reset lock type. */
- (*ldata)->type= TL_UNLOCK;
- }
+ (*ldata)->type= unlock ? TL_UNLOCK : (*ldata)->org_type;
}
diff --git a/sql/log.cc b/sql/log.cc
index e853fedc3d1..7d837938ab4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1753,7 +1753,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
log_query.append("`"))
DBUG_RETURN(1);
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
TRUE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
}
@@ -1777,7 +1777,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
log_query.append("`"))
DBUG_RETURN(1);
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
TRUE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index fb4fc5b79b3..4a1ccc037a5 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -573,7 +573,7 @@ append_query_string(CHARSET_INFO *csinfo,
if (to->reserve(orig_len + from->length()*2+3))
return 1;
- beg= to->c_ptr_quick() + to->length();
+ beg= (char*) to->ptr() + to->length();
ptr= beg;
if (csinfo->escape_with_backslash_is_dangerous)
ptr= str_to_hex(ptr, from->ptr(), from->length());
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
new file mode 100644
index 00000000000..d9dcd354b3e
--- /dev/null
+++ b/sql/multi_range_read.cc
@@ -0,0 +1,1696 @@
+#include "mysql_priv.h"
+#include <my_bit.h>
+#include "sql_select.h"
+
+/****************************************************************************
+ * Default MRR implementation (MRR to non-MRR converter)
+ ***************************************************************************/
+
+/**
+ Get cost and other information about MRR scan over a known list of ranges
+
+ Calculate estimated cost and other information about an MRR scan for given
+ sequence of ranges.
+
+ @param keyno Index number
+ @param seq Range sequence to be traversed
+ @param seq_init_param First parameter for seq->init()
+ @param n_ranges_arg Number of ranges in the sequence, or 0 if the caller
+ can't efficiently determine it
+ @param bufsz INOUT IN: Size of the buffer available for use
+ OUT: Size of the buffer that is expected to be actually
+ used, or 0 if buffer is not needed.
+ @param flags INOUT A combination of HA_MRR_* flags
+ @param cost OUT Estimated cost of MRR access
+
+ @note
+ This method (or an overriding one in a derived class) must check for
+ thd->killed and return HA_POS_ERROR if it is not zero. This is required
+ for a user to be able to interrupt the calculation by killing the
+ connection/query.
+
+ @retval
+ HA_POS_ERROR Error or the engine is unable to perform the requested
+ scan. Values of OUT parameters are undefined.
+ @retval
+ other OK, *cost contains cost of the scan, *bufsz and *flags
+ contain scan parameters.
+*/
+
+ha_rows
+handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param, uint n_ranges_arg,
+ uint *bufsz, uint *flags, COST_VECT *cost)
+{
+ KEY_MULTI_RANGE range;
+ range_seq_t seq_it;
+ ha_rows rows, total_rows= 0;
+ uint n_ranges=0;
+ THD *thd= current_thd;
+
+ /* Default MRR implementation doesn't need buffer */
+ *bufsz= 0;
+
+ seq_it= seq->init(seq_init_param, n_ranges, *flags);
+ while (!seq->next(seq_it, &range))
+ {
+ if (unlikely(thd->killed != 0))
+ return HA_POS_ERROR;
+
+ n_ranges++;
+ key_range *min_endp, *max_endp;
+ if (range.range_flag & GEOM_FLAG)
+ {
+ /* In this case tmp_min_flag contains the handler-read-function */
+ range.start_key.flag= (ha_rkey_function) (range.range_flag ^ GEOM_FLAG);
+ min_endp= &range.start_key;
+ max_endp= NULL;
+ }
+ else
+ {
+ min_endp= range.start_key.length? &range.start_key : NULL;
+ max_endp= range.end_key.length? &range.end_key : NULL;
+ }
+ if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE))
+ rows= 1; /* there can be at most one row */
+ else
+ {
+ if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp,
+ max_endp)))
+ {
+ /* Can't scan one range => can't do MRR scan at all */
+ total_rows= HA_POS_ERROR;
+ break;
+ }
+ }
+ total_rows += rows;
+ }
+
+ if (total_rows != HA_POS_ERROR)
+ {
+ /* The following calculation is the same as in multi_range_read_info(): */
+ *flags |= HA_MRR_USE_DEFAULT_IMPL;
+ cost->zero();
+ cost->avg_io_cost= 1; /* assume random seeks */
+ if ((*flags & HA_MRR_INDEX_ONLY) && total_rows > 2)
+ cost->io_count= keyread_time(keyno, n_ranges, (uint)total_rows);
+ else
+ cost->io_count= read_time(keyno, n_ranges, total_rows);
+ cost->cpu_cost= (double) total_rows / TIME_FOR_COMPARE + 0.01;
+ }
+ return total_rows;
+}
+
+
+/**
+ Get cost and other information about MRR scan over some sequence of ranges
+
+ Calculate estimated cost and other information about an MRR scan for some
+ sequence of ranges.
+
+ The ranges themselves will be known only at execution phase. When this
+ function is called we only know number of ranges and a (rough) E(#records)
+ within those ranges.
+
+ Currently this function is only called for "n-keypart singlepoint" ranges,
+ i.e. each range is "keypart1=someconst1 AND ... AND keypartN=someconstN"
+
+ The flags parameter is a combination of those flags: HA_MRR_SORTED,
+ HA_MRR_INDEX_ONLY, HA_MRR_NO_ASSOCIATION, HA_MRR_LIMITS.
+
+ @param keyno Index number
+ @param n_ranges Estimated number of ranges (i.e. intervals) in the
+ range sequence.
+ @param n_rows Estimated total number of records contained within all
+ of the ranges
+ @param bufsz INOUT IN: Size of the buffer available for use
+ OUT: Size of the buffer that will be actually used, or
+ 0 if buffer is not needed.
+ @param flags INOUT A combination of HA_MRR_* flags
+ @param cost OUT Estimated cost of MRR access
+
+ @retval
+ 0 OK, *cost contains cost of the scan, *bufsz and *flags contain scan
+ parameters.
+ @retval
+ other Error or can't perform the requested scan
+*/
+
+ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost)
+{
+ /*
+ Currently we expect this function to be called only in preparation of scan
+ with HA_MRR_SINGLE_POINT property.
+ */
+ DBUG_ASSERT(*flags | HA_MRR_SINGLE_POINT);
+
+ *bufsz= 0; /* Default implementation doesn't need a buffer */
+ *flags |= HA_MRR_USE_DEFAULT_IMPL;
+
+ cost->zero();
+ cost->avg_io_cost= 1; /* assume random seeks */
+
+ /* Produce the same cost as non-MRR code does */
+ if (*flags & HA_MRR_INDEX_ONLY)
+ cost->io_count= keyread_time(keyno, n_ranges, n_rows);
+ else
+ cost->io_count= read_time(keyno, n_ranges, n_rows);
+ return 0;
+}
+
+
+/**
+ Initialize the MRR scan
+
+ Initialize the MRR scan. This function may do heavyweight scan
+ initialization like row prefetching/sorting/etc (NOTE: but better not do
+ it here as we may not need it, e.g. if we never satisfy WHERE clause on
+ previous tables. For many implementations it would be natural to do such
+ initializations in the first multi_read_range_next() call)
+
+ mode is a combination of the following flags: HA_MRR_SORTED,
+ HA_MRR_INDEX_ONLY, HA_MRR_NO_ASSOCIATION
+
+ @param seq Range sequence to be traversed
+ @param seq_init_param First parameter for seq->init()
+ @param n_ranges Number of ranges in the sequence
+ @param mode Flags, see the description section for the details
+ @param buf INOUT: memory buffer to be used
+
+ @note
+ One must have called index_init() before calling this function. Several
+ multi_range_read_init() calls may be made in course of one query.
+
+ Until WL#2623 is done (see its text, section 3.2), the following will
+ also hold:
+ The caller will guarantee that if "seq->init == mrr_ranges_array_init"
+ then seq_init_param is an array of n_ranges KEY_MULTI_RANGE structures.
+ This property will only be used by NDB handler until WL#2623 is done.
+
+ Buffer memory management is done according to the following scenario:
+ The caller allocates the buffer and provides it to the callee by filling
+ the members of HANDLER_BUFFER structure.
+ The callee consumes all or some fraction of the provided buffer space, and
+ sets the HANDLER_BUFFER members accordingly.
+ The callee may use the buffer memory until the next multi_range_read_init()
+ call is made, all records have been read, or until index_end() call is
+ made, whichever comes first.
+
+ @retval 0 OK
+ @retval 1 Error
+*/
+
+int
+handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
+ uint n_ranges, uint mode, HANDLER_BUFFER *buf)
+{
+ DBUG_ENTER("handler::multi_range_read_init");
+ mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
+ mrr_funcs= *seq_funcs;
+ mrr_is_output_sorted= test(mode & HA_MRR_SORTED);
+ mrr_have_range= FALSE;
+ DBUG_RETURN(0);
+}
+
+/**
+ Get next record in MRR scan
+
+ Default MRR implementation: read the next record
+
+ @param range_info OUT Undefined if HA_MRR_NO_ASSOCIATION flag is in effect
+ Otherwise, the opaque value associated with the range
+ that contains the returned record.
+
+ @retval 0 OK
+ @retval other Error code
+*/
+
+int handler::multi_range_read_next(char **range_info)
+{
+ int result= HA_ERR_END_OF_FILE;
+ bool range_res;
+ DBUG_ENTER("handler::multi_range_read_next");
+
+ if (!mrr_have_range)
+ {
+ mrr_have_range= TRUE;
+ goto start;
+ }
+
+ do
+ {
+ /* Save a call if there can be only one row in range. */
+ if (mrr_cur_range.range_flag != (UNIQUE_RANGE | EQ_RANGE))
+ {
+ result= read_range_next();
+ /* On success or non-EOF errors jump to the end. */
+ if (result != HA_ERR_END_OF_FILE)
+ break;
+ }
+ else
+ {
+ if (was_semi_consistent_read())
+ {
+ /*
+ The following assignment is redundant, but for extra safety and to
+ remove the compiler warning:
+ */
+ range_res= FALSE;
+ goto scan_it_again;
+ }
+ /*
+ We need to set this for the last range only, but checking this
+ condition is more expensive than just setting the result code.
+ */
+ result= HA_ERR_END_OF_FILE;
+ }
+
+start:
+ /* Try the next range(s) until one matches a record. */
+ while (!(range_res= mrr_funcs.next(mrr_iter, &mrr_cur_range)))
+ {
+scan_it_again:
+ result= read_range_first(mrr_cur_range.start_key.keypart_map ?
+ &mrr_cur_range.start_key : 0,
+ mrr_cur_range.end_key.keypart_map ?
+ &mrr_cur_range.end_key : 0,
+ test(mrr_cur_range.range_flag & EQ_RANGE),
+ mrr_is_output_sorted);
+ if (result != HA_ERR_END_OF_FILE)
+ break;
+ }
+ }
+ while ((result == HA_ERR_END_OF_FILE) && !range_res);
+
+ *range_info= mrr_cur_range.ptr;
+ DBUG_PRINT("exit",("handler::multi_range_read_next result %d", result));
+ DBUG_RETURN(result);
+}
+
+/****************************************************************************
+ * Mrr_*_reader classes (building blocks for DS-MRR)
+ ***************************************************************************/
+
+int Mrr_simple_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges,
+ uint mode, Key_parameters *key_par_arg,
+ Lifo_buffer *key_buffer_arg,
+ Buffer_manager *buf_manager_arg)
+{
+ HANDLER_BUFFER no_buffer = {NULL, NULL, NULL};
+ file= h_arg;
+ return file->handler::multi_range_read_init(seq_funcs, seq_init_param,
+ n_ranges, mode, &no_buffer);
+}
+
+
+int Mrr_simple_index_reader::get_next(char **range_info)
+{
+ int res;
+ while (!(res= file->handler::multi_range_read_next(range_info)))
+ {
+ KEY_MULTI_RANGE *curr_range= &file->handler::mrr_cur_range;
+ if (!file->mrr_funcs.skip_index_tuple ||
+ !file->mrr_funcs.skip_index_tuple(file->mrr_iter, curr_range->ptr))
+ break;
+ }
+ return res;
+}
+
+
+/**
+ @brief Get next index record
+
+ @param range_info OUT identifier of range that the returned record belongs to
+
+ @note
+ We actually iterate over nested sequences:
+ - an ordered sequence of groups of identical keys
+ - each key group has key value, which has multiple matching records
+ - thus, each record matches all members of the key group
+
+ @retval 0 OK, next record was successfully read
+ @retval HA_ERR_END_OF_FILE End of records
+ @retval Other Some other error
+*/
+
+int Mrr_ordered_index_reader::get_next(char **range_info)
+{
+ int res;
+ DBUG_ENTER("Mrr_ordered_index_reader::get_next");
+
+ for(;;)
+ {
+ if (!scanning_key_val_iter)
+ {
+ while ((res= kv_it.init(this)))
+ {
+ if ((res != HA_ERR_KEY_NOT_FOUND && res != HA_ERR_END_OF_FILE))
+ DBUG_RETURN(res); /* Some fatal error */
+
+ if (key_buffer->is_empty())
+ {
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+ }
+ }
+ scanning_key_val_iter= TRUE;
+ }
+
+ if ((res= kv_it.get_next(range_info)))
+ {
+ scanning_key_val_iter= FALSE;
+ if ((res != HA_ERR_KEY_NOT_FOUND && res != HA_ERR_END_OF_FILE))
+ DBUG_RETURN(res);
+ kv_it.move_to_next_key_value();
+ continue;
+ }
+ if (!skip_index_tuple(*range_info) &&
+ !skip_record(*range_info, NULL))
+ {
+ break;
+ }
+ /* Go get another (record, range_id) combination */
+ } /* while */
+
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Supply index reader with the O(1)space it needs for scan interrupt/restore
+ operation
+*/
+
+bool Mrr_ordered_index_reader::set_interruption_temp_buffer(uint rowid_length,
+ uint key_len,
+ uchar **space_start,
+ uchar *space_end)
+{
+ if (space_end - *space_start <= (ptrdiff_t)(rowid_length + key_len))
+ return TRUE;
+ support_scan_interruptions= TRUE;
+
+ saved_rowid= *space_start;
+ *space_start += rowid_length;
+ saved_key_tuple= *space_start;
+ *space_start += key_len;
+
+ have_saved_rowid= FALSE;
+ return FALSE;
+}
+
+void Mrr_ordered_index_reader::set_no_interruption_temp_buffer()
+{
+ support_scan_interruptions= FALSE;
+ saved_key_tuple= saved_rowid= NULL; /* safety */
+ have_saved_rowid= FALSE;
+}
+
+void Mrr_ordered_index_reader::interrupt_read()
+{
+ DBUG_ASSERT(support_scan_interruptions);
+ /* Save the current key value */
+ key_copy(saved_key_tuple, file->get_table()->record[0],
+ &file->get_table()->key_info[file->active_index],
+ keypar.key_tuple_length);
+
+ /* Save the last rowid */
+ memcpy(saved_rowid, file->ref, file->ref_length);
+ have_saved_rowid= TRUE;
+}
+
+void Mrr_ordered_index_reader::position()
+{
+ if (have_saved_rowid)
+ memcpy(file->ref, saved_rowid, file->ref_length);
+ else
+ Mrr_index_reader::position();
+}
+
+void Mrr_ordered_index_reader::resume_read()
+{
+ key_restore(file->get_table()->record[0], saved_key_tuple,
+ &file->get_table()->key_info[file->active_index],
+ keypar.key_tuple_length);
+}
+
+
+/**
+ Fill the buffer with (lookup_tuple, range_id) pairs and sort
+*/
+
+int Mrr_ordered_index_reader::refill_buffer(bool initial)
+{
+ KEY_MULTI_RANGE cur_range;
+ DBUG_ENTER("Mrr_ordered_index_reader::refill_buffer");
+
+ DBUG_ASSERT(key_buffer->is_empty());
+
+ if (source_exhausted)
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+
+ buf_manager->reset_buffer_sizes(buf_manager->arg);
+ key_buffer->reset();
+ key_buffer->setup_writing(keypar.key_size_in_keybuf,
+ is_mrr_assoc? sizeof(char*) : 0);
+
+ while (key_buffer->can_write() &&
+ !(source_exhausted= mrr_funcs.next(mrr_iter, &cur_range)))
+ {
+ DBUG_ASSERT(cur_range.range_flag & EQ_RANGE);
+
+ /* Put key, or {key, range_id} pair into the buffer */
+ key_buffer->write_ptr1= keypar.use_key_pointers ?
+ (uchar*)&cur_range.start_key.key :
+ (uchar*)cur_range.start_key.key;
+ key_buffer->write_ptr2= (uchar*)&cur_range.ptr;
+ key_buffer->write();
+ }
+
+ /* Force get_next() to start with kv_it.init() call: */
+ scanning_key_val_iter= FALSE;
+
+ if (source_exhausted && key_buffer->is_empty())
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+
+ key_buffer->sort((key_buffer->type() == Lifo_buffer::FORWARD)?
+ (qsort2_cmp)Mrr_ordered_index_reader::compare_keys_reverse :
+ (qsort2_cmp)Mrr_ordered_index_reader::compare_keys,
+ this);
+ DBUG_RETURN(0);
+}
+
+
+int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges,
+ uint mode, Key_parameters *key_par_arg,
+ Lifo_buffer *key_buffer_arg,
+ Buffer_manager *buf_manager_arg)
+{
+ file= h_arg;
+ key_buffer= key_buffer_arg;
+ buf_manager= buf_manager_arg;
+ keypar= *key_par_arg;
+
+ KEY *key_info= &file->get_table()->key_info[file->active_index];
+ keypar.index_ranges_unique= test(key_info->flags & HA_NOSAME &&
+ key_info->key_parts ==
+ my_count_bits(keypar.key_tuple_map));
+
+ mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
+ is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
+ mrr_funcs= *seq_funcs;
+ source_exhausted= FALSE;
+ if (support_scan_interruptions)
+ bzero(saved_key_tuple, keypar.key_tuple_length);
+ have_saved_rowid= FALSE;
+ return 0;
+}
+
+
+static int rowid_cmp_reverse(void *file, uchar *a, uchar *b)
+{
+ return - ((handler*)file)->cmp_ref(a, b);
+}
+
+
+int Mrr_ordered_rndpos_reader::init(handler *h_arg,
+ Mrr_index_reader *index_reader_arg,
+ uint mode,
+ Lifo_buffer *buf)
+{
+ file= h_arg;
+ index_reader= index_reader_arg;
+ rowid_buffer= buf;
+ is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
+ index_reader_exhausted= FALSE;
+ index_reader_needs_refill= TRUE;
+ return 0;
+}
+
+
+/**
+ DS-MRR: Fill and sort the rowid buffer
+
+ Scan the MRR ranges and collect ROWIDs (or {ROWID, range_id} pairs) into
+ buffer. When the buffer is full or scan is completed, sort the buffer by
+ rowid and return.
+
+ When this function returns, either rowid buffer is not empty, or the source
+ of lookup keys (i.e. ranges) is exhaused.
+
+ @retval 0 OK, the next portion of rowids is in the buffer,
+ properly ordered
+ @retval other Error
+*/
+
+int Mrr_ordered_rndpos_reader::refill_buffer(bool initial)
+{
+ int res;
+ DBUG_ENTER("Mrr_ordered_rndpos_reader::refill_buffer");
+
+ if (index_reader_exhausted)
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+
+ while (initial || index_reader_needs_refill ||
+ (res= refill_from_index_reader()) == HA_ERR_END_OF_FILE)
+ {
+ if ((res= index_reader->refill_buffer(initial)))
+ {
+ if (res == HA_ERR_END_OF_FILE)
+ index_reader_exhausted= TRUE;
+ break;
+ }
+ initial= FALSE;
+ index_reader_needs_refill= FALSE;
+ }
+ DBUG_RETURN(res);
+}
+
+
+void Mrr_index_reader::position()
+{
+ file->position(file->get_table()->record[0]);
+}
+
+
+/*
+ @brief Try to refill the rowid buffer without calling
+ index_reader->refill_buffer().
+*/
+
+int Mrr_ordered_rndpos_reader::refill_from_index_reader()
+{
+ char *range_info;
+ int res;
+ DBUG_ENTER("Mrr_ordered_rndpos_reader::refill_from_index_reader");
+
+ DBUG_ASSERT(rowid_buffer->is_empty());
+ index_rowid= index_reader->get_rowid_ptr();
+ rowid_buffer->reset();
+ rowid_buffer->setup_writing(file->ref_length,
+ is_mrr_assoc? sizeof(char*) : 0);
+
+ last_identical_rowid= NULL;
+
+ index_reader->resume_read();
+ while (rowid_buffer->can_write())
+ {
+ res= index_reader->get_next(&range_info);
+
+ if (res)
+ {
+ if (res != HA_ERR_END_OF_FILE)
+ DBUG_RETURN(res);
+ index_reader_needs_refill=TRUE;
+ break;
+ }
+
+ index_reader->position();
+
+ /* Put rowid, or {rowid, range_id} pair into the buffer */
+ rowid_buffer->write_ptr1= index_rowid;
+ rowid_buffer->write_ptr2= (uchar*)&range_info;
+ rowid_buffer->write();
+ }
+
+ index_reader->interrupt_read();
+ /* Sort the buffer contents by rowid */
+ rowid_buffer->sort((qsort2_cmp)rowid_cmp_reverse, (void*)file);
+
+ rowid_buffer->setup_reading(file->ref_length,
+ is_mrr_assoc ? sizeof(char*) : 0);
+ DBUG_RETURN(rowid_buffer->is_empty()? HA_ERR_END_OF_FILE : 0);
+}
+
+
+/*
+ Get the next {record, range_id} using ordered array of rowid+range_id pairs
+
+ @note
+ Since we have sorted rowids, we try not to make multiple rnd_pos() calls
+ with the same rowid value.
+*/
+
+int Mrr_ordered_rndpos_reader::get_next(char **range_info)
+{
+ int res;
+
+ /*
+ First, check if rowid buffer has elements with the same rowid value as
+ the previous.
+ */
+ while (last_identical_rowid)
+ {
+ /*
+ Current record (the one we've returned in previous call) was obtained
+ from a rowid that matched multiple range_ids. Return this record again,
+ with next matching range_id.
+ */
+ (void)rowid_buffer->read();
+
+ if (rowid_buffer->read_ptr1 == last_identical_rowid)
+ last_identical_rowid= NULL; /* reached the last of identical rowids */
+
+ if (!is_mrr_assoc)
+ return 0;
+
+ memcpy(range_info, rowid_buffer->read_ptr2, sizeof(uchar*));
+ if (!index_reader->skip_record((char*)*range_info, rowid_buffer->read_ptr1))
+ return 0;
+ }
+
+ /*
+ Ok, last_identical_rowid==NULL, it's time to read next different rowid
+ value and get record for it.
+ */
+ for(;;)
+ {
+ /* Return eof if there are no rowids in the buffer after re-fill attempt */
+ if (rowid_buffer->read())
+ return HA_ERR_END_OF_FILE;
+
+ if (is_mrr_assoc)
+ {
+ memcpy(range_info, rowid_buffer->read_ptr2, sizeof(uchar*));
+ if (index_reader->skip_record(*range_info, rowid_buffer->read_ptr1))
+ continue;
+ }
+
+ res= file->ha_rnd_pos(file->get_table()->record[0],
+ rowid_buffer->read_ptr1);
+
+ if (res == HA_ERR_RECORD_DELETED)
+ {
+ /* not likely to get this code with current storage engines, but still */
+ continue;
+ }
+
+ if (res)
+ return res; /* Some fatal error */
+
+ break; /* Got another record */
+ }
+
+ /*
+ Check if subsequent buffer elements have the same rowid value as this
+ one. If yes, remember this fact so that we don't make any more rnd_pos()
+ calls with this value.
+
+ Note: this implies that SQL layer doesn't touch table->record[0]
+ between calls.
+ */
+ Lifo_buffer_iterator it;
+ it.init(rowid_buffer);
+ while (!it.read())
+ {
+ if (file->cmp_ref(it.read_ptr1, rowid_buffer->read_ptr1))
+ break;
+ last_identical_rowid= it.read_ptr1;
+ }
+ return 0;
+}
+
+
+/****************************************************************************
+ * Top-level DS-MRR implementation functions (the ones called by storage engine)
+ ***************************************************************************/
+
+/**
+ DS-MRR: Initialize and start MRR scan
+
+ Initialize and start the MRR scan. Depending on the mode parameter, this
+ may use default or DS-MRR implementation.
+
+ @param h_arg Table handler to be used
+ @param key Index to be used
+ @param seq_funcs Interval sequence enumeration functions
+ @param seq_init_param Interval sequence enumeration parameter
+ @param n_ranges Number of ranges in the sequence.
+ @param mode HA_MRR_* modes to use
+ @param buf INOUT Buffer to use
+
+ @retval 0 Ok, Scan started.
+ @retval other Error
+*/
+
+int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf)
+{
+ THD *thd= current_thd;
+ int res;
+ Key_parameters keypar;
+ uint key_buff_elem_size;
+ handler *h_idx;
+ Mrr_ordered_rndpos_reader *disk_strategy= NULL;
+ bool do_sort_keys= FALSE;
+ DBUG_ENTER("DsMrr_impl::dsmrr_init");
+ LINT_INIT(key_buff_elem_size); /* set/used when do_sort_keys==TRUE */
+ /*
+ index_merge may invoke a scan on an object for which dsmrr_info[_const]
+ has not been called, so set the owner handler here as well.
+ */
+ primary_file= h_arg;
+ is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
+
+ strategy_exhausted= FALSE;
+
+ /* By default, have do-nothing buffer manager */
+ buf_manager.arg= this;
+ buf_manager.reset_buffer_sizes= do_nothing;
+ buf_manager.redistribute_buffer_space= do_nothing;
+
+ if (mode & (HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED))
+ goto use_default_impl;
+
+ /*
+ Determine whether we'll need to do key sorting and/or rnd_pos() scan
+ */
+ index_strategy= NULL;
+ if ((mode & HA_MRR_SINGLE_POINT) &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS))
+ {
+ do_sort_keys= TRUE;
+ index_strategy= &reader_factory.ordered_index_reader;
+ }
+ else
+ index_strategy= &reader_factory.simple_index_reader;
+
+ strategy= index_strategy;
+ /*
+ We don't need a rowid-to-rndpos step if
+ - We're doing a scan on clustered primary key
+ - [In the future] We're doing an index_only read
+ */
+ DBUG_ASSERT(primary_file->inited == handler::INDEX ||
+ (primary_file->inited == handler::RND &&
+ secondary_file &&
+ secondary_file->inited == handler::INDEX));
+
+ h_idx= (primary_file->inited == handler::INDEX)? primary_file: secondary_file;
+ keyno= h_idx->active_index;
+
+ if (!(keyno == table->s->primary_key && h_idx->primary_key_is_clustered()))
+ {
+ strategy= disk_strategy= &reader_factory.ordered_rndpos_reader;
+ }
+
+ if (is_mrr_assoc)
+ status_var_increment(thd->status_var.ha_multi_range_read_init_count);
+
+ full_buf= buf->buffer;
+ full_buf_end= buf->buffer_end;
+
+ if (do_sort_keys)
+ {
+ /* Pre-calculate some parameters of key sorting */
+ keypar.use_key_pointers= test(mode & HA_MRR_MATERIALIZED_KEYS);
+ seq_funcs->get_key_info(seq_init_param, &keypar.key_tuple_length,
+ &keypar.key_tuple_map);
+ keypar.key_size_in_keybuf= keypar.use_key_pointers?
+ sizeof(char*) : keypar.key_tuple_length;
+ key_buff_elem_size= keypar.key_size_in_keybuf + (int)is_mrr_assoc * sizeof(void*);
+
+ /* Ordered index reader needs some space to store an index tuple */
+ if (strategy != index_strategy)
+ {
+ if (reader_factory.ordered_index_reader.
+ set_interruption_temp_buffer(primary_file->ref_length,
+ keypar.key_tuple_length,
+ &full_buf, full_buf_end))
+ goto use_default_impl;
+ }
+ else
+ reader_factory.ordered_index_reader.set_no_interruption_temp_buffer();
+ }
+
+ if (strategy == index_strategy)
+ {
+ /*
+ Index strategy alone handles the record retrieval. Give all buffer space
+ to it. Key buffer should have forward orientation so we can return the
+ end of it.
+ */
+ key_buffer= &forward_key_buf;
+ key_buffer->set_buffer_space(full_buf, full_buf_end);
+
+ /* Safety: specify that rowid buffer has zero size: */
+ rowid_buffer.set_buffer_space(full_buf_end, full_buf_end);
+
+ if (do_sort_keys && !key_buffer->have_space_for(key_buff_elem_size))
+ goto use_default_impl;
+
+ if ((res= index_strategy->init(primary_file, seq_funcs, seq_init_param, n_ranges,
+ mode, &keypar, key_buffer, &buf_manager)))
+ goto error;
+ }
+ else
+ {
+ /* We'll have both index and rndpos strategies working together */
+ if (do_sort_keys)
+ {
+ /* Both strategies will need buffer space, share the buffer */
+ if (setup_buffer_sharing(keypar.key_size_in_keybuf, keypar.key_tuple_map))
+ goto use_default_impl;
+
+ buf_manager.reset_buffer_sizes= reset_buffer_sizes;
+ buf_manager.redistribute_buffer_space= redistribute_buffer_space;
+ }
+ else
+ {
+ /* index strategy doesn't need buffer, give all space to rowids*/
+ rowid_buffer.set_buffer_space(full_buf, full_buf_end);
+ if (!rowid_buffer.have_space_for(primary_file->ref_length +
+ (int)is_mrr_assoc * sizeof(char*)))
+ goto use_default_impl;
+ }
+
+ if ((res= setup_two_handlers()))
+ goto error;
+
+ if ((res= index_strategy->init(secondary_file, seq_funcs, seq_init_param,
+ n_ranges, mode, &keypar, key_buffer,
+ &buf_manager)) ||
+ (res= disk_strategy->init(primary_file, index_strategy, mode,
+ &rowid_buffer)))
+ {
+ goto error;
+ }
+ }
+
+ res= strategy->refill_buffer(TRUE);
+ if (res)
+ {
+ if (res != HA_ERR_END_OF_FILE)
+ goto error;
+ strategy_exhausted= TRUE;
+ }
+
+ /*
+ If we have scanned through all intervals in *seq, then adjust *buf to
+ indicate that the remaining buffer space will not be used.
+ */
+// if (dsmrr_eof)
+// buf->end_of_used_area= rowid_buffer.end_of_space();
+
+
+ DBUG_RETURN(0);
+error:
+ close_second_handler();
+ /* Safety, not really needed but: */
+ strategy= NULL;
+ DBUG_RETURN(1);
+
+use_default_impl:
+ DBUG_ASSERT(primary_file->inited == handler::INDEX);
+ /* Call correct init function and assign to top level object */
+ Mrr_simple_index_reader *s= &reader_factory.simple_index_reader;
+ res= s->init(primary_file, seq_funcs, seq_init_param, n_ranges, mode, NULL,
+ NULL, NULL);
+ strategy= s;
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Whatever the current state is, make it so that we have two handler objects:
+ - primary_file - initialized for rnd_pos() scan
+ - secondary_file - initialized for scanning the index specified in
+ this->keyno
+ RETURN
+ 0 OK
+ HA_XXX Error code
+*/
+
+int DsMrr_impl::setup_two_handlers()
+{
+ int res;
+ THD *thd= primary_file->get_table()->in_use;
+ DBUG_ENTER("DsMrr_impl::setup_two_handlers");
+ if (!secondary_file)
+ {
+ handler *new_h2;
+ Item *pushed_cond= NULL;
+ DBUG_ASSERT(primary_file->inited == handler::INDEX);
+ /* Create a separate handler object to do rnd_pos() calls. */
+ /*
+ ::clone() takes up a lot of stack, especially on 64 bit platforms.
+ The constant 5 is an empiric result.
+ */
+ if (check_stack_overrun(thd, 5*STACK_MIN_SIZE, (uchar*) &new_h2))
+ DBUG_RETURN(1);
+
+ /* Create a separate handler object to do rnd_pos() calls. */
+ if (!(new_h2= primary_file->clone(thd->mem_root)) ||
+ new_h2->ha_external_lock(thd, F_RDLCK))
+ {
+ delete new_h2;
+ DBUG_RETURN(1);
+ }
+
+ if (keyno == primary_file->pushed_idx_cond_keyno)
+ pushed_cond= primary_file->pushed_idx_cond;
+
+ Mrr_reader *save_strategy= strategy;
+ strategy= NULL;
+ /*
+ Caution: this call will invoke this->dsmrr_close(). Do not put the
+ created secondary table handler new_h2 into this->secondary_file or it
+ will delete it. Also, save the picked strategy
+ */
+ res= primary_file->ha_index_end();
+
+ strategy= save_strategy;
+ secondary_file= new_h2;
+
+ if (res || (res= (primary_file->ha_rnd_init(FALSE))))
+ goto error;
+
+ table->prepare_for_position();
+ secondary_file->extra(HA_EXTRA_KEYREAD);
+ secondary_file->mrr_iter= primary_file->mrr_iter;
+
+ if ((res= secondary_file->ha_index_init(keyno, FALSE)))
+ goto error;
+
+ if (pushed_cond)
+ secondary_file->idx_cond_push(keyno, pushed_cond);
+ }
+ else
+ {
+ DBUG_ASSERT(secondary_file && secondary_file->inited==handler::INDEX);
+ /*
+ We get here when the access alternates betwen MRR scan(s) and non-MRR
+ scans.
+
+ Calling primary_file->index_end() will invoke dsmrr_close() for this object,
+ which will delete secondary_file. We need to keep it, so put it away and dont
+ let it be deleted:
+ */
+ if (primary_file->inited == handler::INDEX)
+ {
+ handler *save_h2= secondary_file;
+ Mrr_reader *save_strategy= strategy;
+ secondary_file= NULL;
+ strategy= NULL;
+ res= primary_file->ha_index_end();
+ secondary_file= save_h2;
+ strategy= save_strategy;
+ if (res)
+ goto error;
+ }
+ if ((primary_file->inited != handler::RND) &&
+ (res= primary_file->ha_rnd_init(FALSE)))
+ goto error;
+ }
+ DBUG_RETURN(0);
+
+error:
+ DBUG_RETURN(res);
+}
+
+
+void DsMrr_impl::close_second_handler()
+{
+ if (secondary_file)
+ {
+ secondary_file->ha_index_or_rnd_end();
+ secondary_file->ha_external_lock(current_thd, F_UNLCK);
+ secondary_file->close();
+ delete secondary_file;
+ secondary_file= NULL;
+ }
+}
+
+
+void DsMrr_impl::dsmrr_close()
+{
+ DBUG_ENTER("DsMrr_impl::dsmrr_close");
+ close_second_handler();
+ strategy= NULL;
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ my_qsort2-compatible static member function to compare key tuples
+*/
+
+int Mrr_ordered_index_reader::compare_keys(void* arg, uchar* key1_arg,
+ uchar* key2_arg)
+{
+ Mrr_ordered_index_reader *reader= (Mrr_ordered_index_reader*)arg;
+ TABLE *table= reader->file->get_table();
+ KEY_PART_INFO *part= table->key_info[reader->file->active_index].key_part;
+ uchar *key1, *key2;
+
+ if (reader->keypar.use_key_pointers)
+ {
+ /* the buffer stores pointers to keys, get to the keys */
+ memcpy(&key1, key1_arg, sizeof(char*));
+ memcpy(&key2, key2_arg, sizeof(char*));
+ }
+ else
+ {
+ key1= key1_arg;
+ key2= key2_arg;
+ }
+
+ return key_tuple_cmp(part, key1, key2, reader->keypar.key_tuple_length);
+}
+
+
+int Mrr_ordered_index_reader::compare_keys_reverse(void* arg, uchar* key1,
+ uchar* key2)
+{
+ return -compare_keys(arg, key1, key2);
+}
+
+
+/**
+ Set the buffer space to be shared between rowid and key buffer
+
+ @return FALSE ok
+ @return TRUE There is so little buffer space that we won't be able to use
+ the strategy.
+ This happens when we don't have enough space for one rowid
+ element and one key element so this is mainly targeted at
+ testing.
+*/
+
+bool DsMrr_impl::setup_buffer_sharing(uint key_size_in_keybuf,
+ key_part_map key_tuple_map)
+{
+ long key_buff_elem_size= key_size_in_keybuf +
+ (int)is_mrr_assoc * sizeof(void*);
+
+ KEY *key_info= &primary_file->get_table()->key_info[keyno];
+ /*
+ Ok if we got here we need to allocate one part of the buffer
+ for keys and another part for rowids.
+ */
+ ulonglong rowid_buf_elem_size= primary_file->ref_length +
+ (int)is_mrr_assoc * sizeof(char*);
+
+ /*
+ Use rec_per_key statistics as a basis to find out how many rowids
+ we'll get for each key value.
+ TODO: what should be the default value to use when there is no
+ statistics?
+ */
+ uint parts= my_count_bits(key_tuple_map);
+ ulong rpc;
+ ulonglong rowids_size= rowid_buf_elem_size;
+ if ((rpc= key_info->rec_per_key[parts - 1]))
+ rowids_size= rowid_buf_elem_size * rpc;
+
+ double fraction_for_rowids=
+ (ulonglong2double(rowids_size) /
+ (ulonglong2double(rowids_size) + key_buff_elem_size));
+
+ ptrdiff_t bytes_for_rowids=
+ (ptrdiff_t)floor(0.5 + fraction_for_rowids * (full_buf_end - full_buf));
+
+ ptrdiff_t bytes_for_keys= (full_buf_end - full_buf) - bytes_for_rowids;
+
+ if (bytes_for_keys < key_buff_elem_size + 1)
+ {
+ ptrdiff_t add= key_buff_elem_size + 1 - bytes_for_keys;
+ bytes_for_keys= key_buff_elem_size + 1;
+ bytes_for_rowids -= add;
+ }
+
+ if (bytes_for_rowids < (ptrdiff_t)rowid_buf_elem_size + 1)
+ {
+ ptrdiff_t add= rowid_buf_elem_size + 1 - bytes_for_rowids;
+ bytes_for_rowids= rowid_buf_elem_size + 1;
+ bytes_for_keys -= add;
+ }
+
+ rowid_buffer_end= full_buf + bytes_for_rowids;
+ rowid_buffer.set_buffer_space(full_buf, rowid_buffer_end);
+ key_buffer= &backward_key_buf;
+ key_buffer->set_buffer_space(rowid_buffer_end, full_buf_end);
+
+ if (!key_buffer->have_space_for(key_buff_elem_size) ||
+ !rowid_buffer.have_space_for(rowid_buf_elem_size))
+ return TRUE; /* Failed to provide minimum space for one of the buffers */
+
+ return FALSE;
+}
+
+
+void DsMrr_impl::do_nothing(void *dsmrr_arg)
+{
+ /* Do nothing */
+}
+
+
+void DsMrr_impl::reset_buffer_sizes(void *dsmrr_arg)
+{
+ DsMrr_impl *dsmrr= (DsMrr_impl*)dsmrr_arg;
+ dsmrr->rowid_buffer.set_buffer_space(dsmrr->full_buf,
+ dsmrr->rowid_buffer_end);
+ dsmrr->key_buffer->set_buffer_space(dsmrr->rowid_buffer_end,
+ dsmrr->full_buf_end);
+}
+
+
+/*
+ Take unused space from the key buffer and give it to the rowid buffer
+*/
+
+void DsMrr_impl::redistribute_buffer_space(void *dsmrr_arg)
+{
+ DsMrr_impl *dsmrr= (DsMrr_impl*)dsmrr_arg;
+ uchar *unused_start, *unused_end;
+ dsmrr->key_buffer->remove_unused_space(&unused_start, &unused_end);
+ dsmrr->rowid_buffer.grow(unused_start, unused_end);
+}
+
+
+/*
+ @brief Initialize the iterator
+
+ @note
+ Initialize the iterator to produce matches for the key of the first element
+ in owner_arg->key_buffer
+
+ @retval 0 OK
+ @retval HA_ERR_END_OF_FILE Either the owner->key_buffer is empty or
+ no matches for the key we've tried (check
+ key_buffer->is_empty() to tell these apart)
+ @retval other code Fatal error
+*/
+
+int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
+{
+ int res;
+ owner= owner_arg;
+
+ identical_key_it.init(owner->key_buffer);
+ owner->key_buffer->setup_reading(owner->keypar.key_size_in_keybuf,
+ owner->is_mrr_assoc ? sizeof(void*) : 0);
+
+ if (identical_key_it.read())
+ return HA_ERR_END_OF_FILE;
+
+ uchar *key_in_buf= last_identical_key_ptr= identical_key_it.read_ptr1;
+
+ uchar *index_tuple= key_in_buf;
+ if (owner->keypar.use_key_pointers)
+ memcpy(&index_tuple, key_in_buf, sizeof(char*));
+
+ /* Check out how many more identical keys are following */
+ while (!identical_key_it.read())
+ {
+ if (Mrr_ordered_index_reader::compare_keys(owner, key_in_buf,
+ identical_key_it.read_ptr1))
+ break;
+ last_identical_key_ptr= identical_key_it.read_ptr1;
+ }
+ identical_key_it.init(owner->key_buffer);
+ res= owner->file->ha_index_read_map(owner->file->get_table()->record[0],
+ index_tuple,
+ owner->keypar.key_tuple_map,
+ HA_READ_KEY_EXACT);
+
+ if (res)
+ {
+ /* Failed to find any matching records */
+ move_to_next_key_value();
+ return res;
+ }
+ owner->have_saved_rowid= FALSE;
+ get_next_row= FALSE;
+ return 0;
+}
+
+
+int Key_value_records_iterator::get_next(char **range_info)
+{
+ int res;
+
+ if (get_next_row)
+ {
+ if (owner->keypar.index_ranges_unique)
+ {
+ /* We're using a full unique key, no point to call index_next_same */
+ return HA_ERR_END_OF_FILE;
+ }
+
+ handler *h= owner->file;
+ if ((res= h->ha_index_next_same(h->get_table()->record[0],
+ identical_key_it.read_ptr1,
+ owner->keypar.key_tuple_length)))
+ {
+ /* It's either HA_ERR_END_OF_FILE or some other error */
+ return res;
+ }
+ identical_key_it.init(owner->key_buffer);
+ owner->have_saved_rowid= FALSE;
+ get_next_row= FALSE;
+ }
+
+ identical_key_it.read(); /* This gets us next range_id */
+ memcpy(range_info, identical_key_it.read_ptr2, sizeof(char*));
+
+ if (!last_identical_key_ptr ||
+ (identical_key_it.read_ptr1 == last_identical_key_ptr))
+ {
+ /*
+ We've reached the last of the identical keys that current record is a
+ match for. Set get_next_row=TRUE so that we read the next index record
+ on the next call to this function.
+ */
+ get_next_row= TRUE;
+ }
+ return 0;
+}
+
+
+void Key_value_records_iterator::move_to_next_key_value()
+{
+ while (!owner->key_buffer->read() &&
+ (owner->key_buffer->read_ptr1 != last_identical_key_ptr)) {}
+}
+
+
+/**
+ DS-MRR implementation: multi_range_read_next() function.
+
+ Calling convention is like multi_range_read_next() has.
+*/
+
+int DsMrr_impl::dsmrr_next(char **range_info)
+{
+ int res;
+ if (strategy_exhausted)
+ return HA_ERR_END_OF_FILE;
+
+ while ((res= strategy->get_next(range_info)) == HA_ERR_END_OF_FILE)
+ {
+ if ((res= strategy->refill_buffer(FALSE)))
+ break; /* EOF or error */
+ }
+ return res;
+}
+
+
+/**
+ DS-MRR implementation: multi_range_read_info() function
+*/
+ha_rows DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows,
+ uint key_parts,
+ uint *bufsz, uint *flags, COST_VECT *cost)
+{
+ ha_rows res;
+ uint def_flags= *flags;
+ uint def_bufsz= *bufsz;
+
+ /* Get cost/flags/mem_usage of default MRR implementation */
+ res= primary_file->handler::multi_range_read_info(keyno, n_ranges, rows,
+ key_parts, &def_bufsz,
+ &def_flags, cost);
+ DBUG_ASSERT(!res);
+
+ if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
+ choose_mrr_impl(keyno, rows, &def_flags, &def_bufsz, cost))
+ {
+ /* Default implementation is choosen */
+ DBUG_PRINT("info", ("Default MRR implementation choosen"));
+ *flags= def_flags;
+ *bufsz= def_bufsz;
+ }
+ else
+ {
+ /* *flags and *bufsz were set by choose_mrr_impl */
+ DBUG_PRINT("info", ("DS-MRR implementation choosen"));
+ }
+ return 0;
+}
+
+
+/**
+ DS-MRR Implementation: multi_range_read_info_const() function
+*/
+
+ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param, uint n_ranges,
+ uint *bufsz, uint *flags, COST_VECT *cost)
+{
+ ha_rows rows;
+ uint def_flags= *flags;
+ uint def_bufsz= *bufsz;
+ /* Get cost/flags/mem_usage of default MRR implementation */
+ rows= primary_file->handler::multi_range_read_info_const(keyno, seq,
+ seq_init_param,
+ n_ranges,
+ &def_bufsz,
+ &def_flags, cost);
+ if (rows == HA_POS_ERROR)
+ {
+ /* Default implementation can't perform MRR scan => we can't either */
+ return rows;
+ }
+
+ /*
+ If HA_MRR_USE_DEFAULT_IMPL has been passed to us, that is an order to
+ use the default MRR implementation (we need it for UPDATE/DELETE).
+ Otherwise, make a choice based on cost and @@optimizer_use_mrr.
+ */
+ if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
+ choose_mrr_impl(keyno, rows, flags, bufsz, cost))
+ {
+ DBUG_PRINT("info", ("Default MRR implementation choosen"));
+ *flags= def_flags;
+ *bufsz= def_bufsz;
+ }
+ else
+ {
+ /* *flags and *bufsz were set by choose_mrr_impl */
+ DBUG_PRINT("info", ("DS-MRR implementation choosen"));
+ }
+ return rows;
+}
+
+
+/**
+ Check if key has partially-covered columns
+
+ We can't use DS-MRR to perform range scans when the ranges are over
+ partially-covered keys, because we'll not have full key part values
+ (we'll have their prefixes from the index) and will not be able to check
+ if we've reached the end the range.
+
+ @param keyno Key to check
+
+ @todo
+ Allow use of DS-MRR in cases where the index has partially-covered
+ components but they are not used for scanning.
+
+ @retval TRUE Yes
+ @retval FALSE No
+*/
+
+bool key_uses_partial_cols(TABLE *table, uint keyno)
+{
+ KEY_PART_INFO *kp= table->key_info[keyno].key_part;
+ KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts;
+ for (; kp != kp_end; kp++)
+ {
+ if (!kp->field->part_of_key.is_set(keyno))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Check if key/flags allow DS-MRR/CPK strategy to be used
+
+ @param thd
+ @param keyno Index that will be used
+ @param mrr_flags
+
+ @retval TRUE DS-MRR/CPK should be used
+ @retval FALSE Otherwise
+*/
+
+bool DsMrr_impl::check_cpk_scan(THD *thd, uint keyno, uint mrr_flags)
+{
+ return test((mrr_flags & HA_MRR_SINGLE_POINT) &&
+ keyno == table->s->primary_key &&
+ primary_file->primary_key_is_clustered() &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS));
+}
+
+
+/*
+ DS-MRR Internals: Choose between Default MRR implementation and DS-MRR
+
+ Make the choice between using Default MRR implementation and DS-MRR.
+ This function contains common functionality factored out of dsmrr_info()
+ and dsmrr_info_const(). The function assumes that the default MRR
+ implementation's applicability requirements are satisfied.
+
+ @param keyno Index number
+ @param rows E(full rows to be retrieved)
+ @param flags IN MRR flags provided by the MRR user
+ OUT If DS-MRR is choosen, flags of DS-MRR implementation
+ else the value is not modified
+ @param bufsz IN If DS-MRR is choosen, buffer use of DS-MRR implementation
+ else the value is not modified
+ @param cost IN Cost of default MRR implementation
+ OUT If DS-MRR is choosen, cost of DS-MRR scan
+ else the value is not modified
+
+ @retval TRUE Default MRR implementation should be used
+ @retval FALSE DS-MRR implementation should be used
+*/
+
+
+bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
+ uint *bufsz, COST_VECT *cost)
+{
+ COST_VECT dsmrr_cost;
+ bool res;
+ THD *thd= current_thd;
+
+ bool doing_cpk_scan= check_cpk_scan(thd, keyno, *flags);
+ bool using_cpk= test(keyno == table->s->primary_key &&
+ primary_file->primary_key_is_clustered());
+ if (thd->variables.optimizer_use_mrr == 2 || *flags & HA_MRR_INDEX_ONLY ||
+ (using_cpk && !doing_cpk_scan) || key_uses_partial_cols(table, keyno))
+ {
+ /* Use the default implementation */
+ *flags |= HA_MRR_USE_DEFAULT_IMPL;
+ return TRUE;
+ }
+
+ uint add_len= table->key_info[keyno].key_length + primary_file->ref_length;
+ *bufsz -= add_len;
+ if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
+ return TRUE;
+ *bufsz += add_len;
+
+ bool force_dsmrr;
+ /*
+ If @@optimizer_use_mrr==force, then set cost of DS-MRR to be minimum of
+ DS-MRR and Default implementations cost. This allows one to force use of
+ DS-MRR whenever it is applicable without affecting other cost-based
+ choices.
+ */
+ if ((force_dsmrr= (thd->variables.optimizer_use_mrr == 1)) &&
+ dsmrr_cost.total_cost() > cost->total_cost())
+ dsmrr_cost= *cost;
+
+ if (force_dsmrr || dsmrr_cost.total_cost() <= cost->total_cost())
+ {
+ *flags &= ~HA_MRR_USE_DEFAULT_IMPL; /* Use the DS-MRR implementation */
+ *flags &= ~HA_MRR_SORTED; /* We will return unordered output */
+ *cost= dsmrr_cost;
+ res= FALSE;
+
+ if ((*flags & HA_MRR_SINGLE_POINT) &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS))
+ *flags |= HA_MRR_MATERIALIZED_KEYS;
+ }
+ else
+ {
+ /* Use the default MRR implementation */
+ res= TRUE;
+ }
+ return res;
+}
+
+
+static void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, COST_VECT *cost);
+
+
+/**
+ Get cost of DS-MRR scan
+
+ @param keynr Index to be used
+ @param rows E(Number of rows to be scanned)
+ @param flags Scan parameters (HA_MRR_* flags)
+ @param buffer_size INOUT Buffer size
+ @param cost OUT The cost
+
+ @retval FALSE OK
+ @retval TRUE Error, DS-MRR cannot be used (the buffer is too small
+ for even 1 rowid)
+*/
+
+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;
+ uint n_full_steps;
+ double index_read_cost;
+
+ elem_size= primary_file->ref_length +
+ sizeof(void*) * (!test(flags & HA_MRR_NO_ASSOCIATION));
+ max_buff_entries = *buffer_size / elem_size;
+
+ if (!max_buff_entries)
+ return TRUE; /* Buffer has not enough space for even 1 rowid */
+
+ /* Number of iterations we'll make with full buffer */
+ n_full_steps= (uint)floor(rows2double(rows) / max_buff_entries);
+
+ /*
+ Get numbers of rows we'll be processing in
+ - non-last sweep, with full buffer
+ - last iteration, with non-full buffer
+ */
+ rows_in_full_step= max_buff_entries;
+ rows_in_last_step= rows % max_buff_entries;
+
+ /* 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);
+ cost->multiply(n_full_steps);
+ }
+ else
+ {
+ cost->zero();
+ *buffer_size= max(*buffer_size,
+ (size_t)(1.2*rows_in_last_step) * elem_size +
+ primary_file->ref_length + table->key_info[keynr].key_length);
+ }
+
+ COST_VECT last_step_cost;
+ get_sort_and_sweep_cost(table, rows_in_last_step, &last_step_cost);
+ cost->add(&last_step_cost);
+
+ if (n_full_steps != 0)
+ cost->mem_cost= *buffer_size;
+ else
+ cost->mem_cost= (double)rows_in_last_step * elem_size;
+
+ /* Total cost of all index accesses */
+ index_read_cost= primary_file->keyread_time(keynr, 1, rows);
+ cost->add_io(index_read_cost, 1 /* Random seeks */);
+ return FALSE;
+}
+
+
+/*
+ Get cost of one sort-and-sweep step
+
+ It consists of two parts:
+ - sort an array of #nrows ROWIDs using qsort
+ - read #nrows records from table in a sweep.
+
+ @param table Table being accessed
+ @param nrows Number of rows to be sorted and retrieved
+ @param cost OUT The cost of scan
+*/
+
+static
+void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, COST_VECT *cost)
+{
+ if (nrows)
+ {
+ get_sweep_read_cost(table, nrows, FALSE, cost);
+ /* Add cost of qsort call: n * log2(n) * cost(rowid_comparison) */
+ double cmp_op= rows2double(nrows) * (1.0 / TIME_FOR_COMPARE_ROWID);
+ if (cmp_op < 3)
+ cmp_op= 3;
+ cost->cpu_cost += cmp_op * log2(cmp_op);
+ }
+ else
+ cost->zero();
+}
+
+
+/**
+ Get cost of reading nrows table records in a "disk sweep"
+
+ A disk sweep read is a sequence of handler->rnd_pos(rowid) calls that made
+ for an ordered sequence of rowids.
+
+ We assume hard disk IO. The read is performed as follows:
+
+ 1. The disk head is moved to the needed cylinder
+ 2. The controller waits for the plate to rotate
+ 3. The data is transferred
+
+ Time to do #3 is insignificant compared to #2+#1.
+
+ Time to move the disk head is proportional to head travel distance.
+
+ Time to wait for the plate to rotate depends on whether the disk head
+ was moved or not.
+
+ If disk head wasn't moved, the wait time is proportional to distance
+ between the previous block and the block we're reading.
+
+ If the head was moved, we don't know how much we'll need to wait for the
+ plate to rotate. We assume the wait time to be a variate with a mean of
+ 0.5 of full rotation time.
+
+ Our cost units are "random disk seeks". The cost of random disk seek is
+ actually not a constant, it depends one range of cylinders we're going
+ to access. We make it constant by introducing a fuzzy concept of "typical
+ datafile length" (it's fuzzy as it's hard to tell whether it should
+ include index file, temp.tables etc). Then random seek cost is:
+
+ 1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length
+
+ We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9.
+
+ @param table Table to be accessed
+ @param nrows Number of rows to retrieve
+ @param interrupted TRUE <=> Assume that the disk sweep will be
+ interrupted by other disk IO. FALSE - otherwise.
+ @param cost OUT The cost.
+*/
+
+void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
+ COST_VECT *cost)
+{
+ DBUG_ENTER("get_sweep_read_cost");
+
+ cost->zero();
+ if (table->file->primary_key_is_clustered())
+ {
+ cost->io_count= table->file->read_time(table->s->primary_key,
+ (uint) nrows, nrows);
+ }
+ else
+ {
+ double n_blocks=
+ ceil(ulonglong2double(table->file->stats.data_file_length) / IO_SIZE);
+ double busy_blocks=
+ n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
+ if (busy_blocks < 1.0)
+ busy_blocks= 1.0;
+
+ DBUG_PRINT("info",("sweep: nblocks=%g, busy_blocks=%g", n_blocks,
+ busy_blocks));
+ cost->io_count= busy_blocks;
+
+ if (!interrupted)
+ {
+ /* Assume reading is done in one 'sweep' */
+ cost->avg_io_cost= (DISK_SEEK_BASE_COST +
+ DISK_SEEK_PROP_COST*n_blocks/busy_blocks);
+ }
+ }
+ DBUG_PRINT("info",("returning cost=%g", cost->total_cost()));
+ DBUG_VOID_RETURN;
+}
+
+
+/* **************************************************************************
+ * DS-MRR implementation ends
+ ***************************************************************************/
+
+
diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h
new file mode 100644
index 00000000000..fb0cd738855
--- /dev/null
+++ b/sql/multi_range_read.h
@@ -0,0 +1,623 @@
+/**
+ @defgroup DS-MRR declarations
+ @{
+*/
+
+/**
+ A Disk-Sweep implementation of MRR Interface (DS-MRR for short)
+
+ This is a "plugin"(*) for storage engines that allows to
+ 1. When doing index scans, read table rows in rowid order;
+ 2. when making many index lookups, do them in key order and don't
+ lookup the same key value multiple times;
+ 3. Do both #1 and #2, when applicable.
+ These changes are expected to speed up query execution for disk-based
+ storage engines running io-bound loads and "big" queries (ie. queries that
+ do joins and enumerate lots of records).
+
+ (*) - only conceptually. No dynamic loading or binary compatibility of any
+ kind.
+
+ General scheme of things:
+
+ SQL Layer code
+ | | |
+ v v v
+ -|---|---|---- handler->multi_range_read_XXX() function calls
+ | | |
+ _____________________________________
+ / DS-MRR module \
+ | (order/de-duplicate lookup keys, |
+ | scan indexes in key order, |
+ | order/de-duplicate rowids, |
+ | retrieve full record reads in rowid |
+ | order) |
+ \_____________________________________/
+ | | |
+ -|---|---|----- handler->read_range_first()/read_range_next(),
+ | | | handler->index_read(), handler->rnd_pos() calls.
+ | | |
+ v v v
+ Storage engine internals
+
+
+ Currently DS-MRR is used by MyISAM, InnoDB/XtraDB and Maria storage engines.
+ Potentially it can be used with any table handler that has disk-based data
+ storage and has better performance when reading data in rowid order.
+*/
+
+#include "sql_lifo_buffer.h"
+
+class DsMrr_impl;
+class Mrr_ordered_index_reader;
+
+
+/* A structure with key parameters that's shared among several classes */
+class Key_parameters
+{
+public:
+ uint key_tuple_length; /* Length of index lookup tuple, in bytes */
+ key_part_map key_tuple_map; /* keyparts used in index lookup tuples */
+
+ /*
+ This is
+ = key_tuple_length if we copy keys to buffer
+ = sizeof(void*) if we're using pointers to materialized keys.
+ */
+ uint key_size_in_keybuf;
+
+ /* TRUE <=> don't copy key values, use pointers to them instead. */
+ bool use_key_pointers;
+
+ /* TRUE <=> We can get at most one index tuple for a lookup key */
+ bool index_ranges_unique;
+};
+
+
+/**
+ A class to enumerate (record, range_id) pairs that match given key value.
+
+ @note
+
+ The idea is that we have a Lifo_buffer which holds (key, range_id) pairs
+ ordered by key value. From the front of the buffer we see
+
+ (key_val1, range_id1), (key_val1, range_id2) ... (key_val2, range_idN)
+
+ we take the first elements that have the same key value (key_val1 in the
+ example above), and make lookup into the table. The table will have
+ multiple matches for key_val1:
+
+ == Table Index ==
+ ...
+ key_val1 -> key_val1, index_tuple1
+ key_val1, index_tuple2
+ ...
+ key_val1, index_tupleN
+ ...
+
+ Our goal is to produce all possible combinations, i.e. we need:
+
+ {(key_val1, index_tuple1), range_id1}
+ {(key_val1, index_tuple1), range_id2}
+ ... ... |
+ {(key_val1, index_tuple1), range_idN},
+
+ {(key_val1, index_tuple2), range_id1}
+ {(key_val1, index_tuple2), range_id2}
+ ... ... |
+ {(key_val1, index_tuple2), range_idN},
+
+ ... ... ...
+
+ {(key_val1, index_tupleK), range_idN}
+*/
+
+class Key_value_records_iterator
+{
+ /* Use this to get table handler, key buffer and other parameters */
+ Mrr_ordered_index_reader *owner;
+
+ /* Iterator to get (key, range_id) pairs from */
+ Lifo_buffer_iterator identical_key_it;
+
+ /*
+ Last of the identical key values (when we get this pointer from
+ identical_key_it, it will be time to stop).
+ */
+ uchar *last_identical_key_ptr;
+
+ /*
+ FALSE <=> we're right after the init() call, the record has been already
+ read with owner->file->index_read_map() call
+ */
+ bool get_next_row;
+
+public:
+ int init(Mrr_ordered_index_reader *owner_arg);
+ int get_next(char **range_info);
+ void move_to_next_key_value();
+};
+
+
+/*
+ Buffer manager interface. Mrr_reader objects use it to inqure DsMrr_impl
+ to manage buffer space for them.
+*/
+typedef struct st_buffer_manager
+{
+public:
+ /* Opaque value to be passed as the first argument to all member functions */
+ void *arg;
+
+ /*
+ This is called when we've freed more space from the rowid buffer. The
+ callee will get the unused space from the rowid buffer and give it to the
+ key buffer.
+ */
+ void (*redistribute_buffer_space)(void *arg);
+
+ /*
+ This is called when both key and rowid buffers are empty, and so it's time
+ to reset them to their original size (They've lost their original size,
+ because we were dynamically growing rowid buffer and shrinking key buffer).
+ */
+ void (*reset_buffer_sizes)(void *arg);
+
+} Buffer_manager;
+
+
+/*
+ Mrr_reader - DS-MRR execution strategy abstraction
+
+ A reader produces ([index]_record, range_info) pairs, and requires periodic
+ refill operations.
+
+ - one starts using the reader by calling reader->get_next(),
+ - when a get_next() call returns HA_ERR_END_OF_FILE, one must call
+ refill_buffer() before they can make more get_next() calls.
+ - when refill_buffer() returns HA_ERR_END_OF_FILE, this means the real
+ end of stream and get_next() should not be called anymore.
+
+ Both functions can return other error codes, these mean unrecoverable errors
+ after which one cannot continue.
+*/
+
+class Mrr_reader
+{
+public:
+ virtual int get_next(char **range_info) = 0;
+ virtual int refill_buffer(bool initial) = 0;
+ virtual ~Mrr_reader() {}; /* just to remove compiler warning */
+};
+
+
+/*
+ A common base for readers that do index scans and produce index tuples
+*/
+
+class Mrr_index_reader : public Mrr_reader
+{
+protected:
+ handler *file; /* Handler object to use */
+public:
+ virtual int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges,
+ uint mode, Key_parameters *key_par,
+ Lifo_buffer *key_buffer,
+ Buffer_manager *buf_manager_arg) = 0;
+
+ /* Get pointer to place where every get_next() call will put rowid */
+ virtual uchar *get_rowid_ptr() = 0;
+ /* Get the rowid (call this after get_next() call) */
+ virtual void position();
+ virtual bool skip_record(char *range_id, uchar *rowid) = 0;
+
+ virtual void interrupt_read() {}
+ virtual void resume_read() {}
+};
+
+
+/*
+ A "bypass" index reader that just does and index scan. The index scan is done
+ by calling default MRR implementation (i.e. handler::multi_range_read_XXX())
+ functions.
+*/
+
+class Mrr_simple_index_reader : public Mrr_index_reader
+{
+public:
+ int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges,
+ uint mode, Key_parameters *key_par,
+ Lifo_buffer *key_buffer,
+ Buffer_manager *buf_manager_arg);
+ int get_next(char **range_info);
+ int refill_buffer(bool initial) { return initial? 0: HA_ERR_END_OF_FILE; }
+ uchar *get_rowid_ptr() { return file->ref; }
+ bool skip_record(char *range_id, uchar *rowid)
+ {
+ return (file->mrr_funcs.skip_record &&
+ file->mrr_funcs.skip_record(file->mrr_iter, range_id, rowid));
+ }
+};
+
+
+/*
+ A reader that sorts the key values before it makes the index lookups.
+*/
+
+class Mrr_ordered_index_reader : public Mrr_index_reader
+{
+public:
+ int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges,
+ uint mode, Key_parameters *key_par,
+ Lifo_buffer *key_buffer,
+ Buffer_manager *buf_manager_arg);
+ int get_next(char **range_info);
+ int refill_buffer(bool initial);
+ uchar *get_rowid_ptr() { return file->ref; }
+
+ bool skip_record(char *range_info, uchar *rowid)
+ {
+ return (mrr_funcs.skip_record &&
+ mrr_funcs.skip_record(mrr_iter, range_info, rowid));
+ }
+
+ bool skip_index_tuple(char *range_info)
+ {
+ return (mrr_funcs.skip_index_tuple &&
+ mrr_funcs.skip_index_tuple(mrr_iter, range_info));
+ }
+
+ bool set_interruption_temp_buffer(uint rowid_length, uint key_len,
+ uchar **space_start, uchar *space_end);
+ void set_no_interruption_temp_buffer();
+
+ void interrupt_read();
+ void resume_read();
+ void position();
+private:
+ Key_value_records_iterator kv_it;
+
+ bool scanning_key_val_iter;
+
+ /* Buffer to store (key, range_id) pairs */
+ Lifo_buffer *key_buffer;
+
+ /* This manages key buffer allocation and sizing for us */
+ Buffer_manager *buf_manager;
+
+ Key_parameters keypar; /* index scan and lookup tuple parameters */
+
+ /* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
+ bool is_mrr_assoc;
+
+ /* Range sequence iteration members */
+ RANGE_SEQ_IF mrr_funcs;
+ range_seq_t mrr_iter;
+
+ /* TRUE == reached eof when enumerating ranges */
+ bool source_exhausted;
+
+ bool support_scan_interruptions;
+ /*
+ Space where we save the rowid of the last record we've returned. This is
+ needed for the cases where index scan is interrupted by some other activity
+ that destroys contents in file->record[0] (which some storage engines use
+ to store the last rowid value)
+ */
+ uchar *saved_rowid;
+
+ /* TRUE <=> saved_rowid has the last saved rowid */
+ bool have_saved_rowid;
+
+ uchar *saved_key_tuple;
+
+ static int compare_keys(void* arg, uchar* key1, uchar* key2);
+ static int compare_keys_reverse(void* arg, uchar* key1, uchar* key2);
+
+ friend class Key_value_records_iterator;
+ friend class DsMrr_impl;
+ friend class Mrr_ordered_rndpos_reader;
+};
+
+
+/*
+ A reader that gets rowids from an Mrr_index_reader, and then sorts them
+ before getting full records with handler->rndpos() calls.
+*/
+
+class Mrr_ordered_rndpos_reader : public Mrr_reader
+{
+public:
+ int init(handler *file, Mrr_index_reader *index_reader, uint mode,
+ Lifo_buffer *buf);
+ int get_next(char **range_info);
+ int refill_buffer(bool initial);
+private:
+ handler *file; /* Handler to use */
+
+ /* This what we get (rowid, range_info) pairs from */
+ Mrr_index_reader *index_reader;
+
+ /* index_reader->get_next() puts rowid here */
+ uchar *index_rowid;
+
+ /* TRUE <=> index_reader->refill_buffer() call has returned EOF */
+ bool index_reader_exhausted;
+
+ /*
+ TRUE <=> We should call index_reader->refill_buffer(). This happens if
+ 1. we've made index_reader->get_next() call which returned EOF
+ 2. we haven't made any index_reader calls (and our first call should
+ be index_reader->refill_buffer(initial=TRUE)
+ */
+ bool index_reader_needs_refill;
+
+ /* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
+ bool is_mrr_assoc;
+
+ /*
+ When reading from ordered rowid buffer: the rowid element of the last
+ buffer element that has rowid identical to this one.
+ */
+ uchar *last_identical_rowid;
+
+ /* Buffer to store (rowid, range_id) pairs */
+ Lifo_buffer *rowid_buffer;
+
+ int refill_from_index_reader();
+};
+
+
+/*
+ A primitive "factory" of various Mrr_*_reader classes (the point is to
+ get various kinds of readers without having to allocate them on the heap)
+*/
+
+class Mrr_reader_factory
+{
+public:
+ Mrr_ordered_rndpos_reader ordered_rndpos_reader;
+ Mrr_ordered_index_reader ordered_index_reader;
+ Mrr_simple_index_reader simple_index_reader;
+};
+
+
+/*
+ DS-MRR implementation for one table. Create/use one object of this class for
+ each ha_{myisam/innobase/etc} object. That object will be further referred to
+ as "the handler"
+
+ DsMrr_impl supports has the following execution strategies:
+
+ - Bypass DS-MRR, pass all calls to default MRR implementation, which is
+ an MRR-to-non-MRR call converter.
+ - Key-Ordered Retrieval
+ - Rowid-Ordered Retrieval
+
+ DsMrr_impl will use one of the above strategies, or a combination of them,
+ according to the following diagram:
+
+ (mrr function calls)
+ |
+ +----------------->-----------------+
+ | |
+ ___________v______________ _______________v________________
+ / default: use lookup keys \ / KEY-ORDERED RETRIEVAL: \
+ | (or ranges) in whatever | | sort lookup keys and then make |
+ | order they are supplied | | index lookups in index order |
+ \__________________________/ \________________________________/
+ | | | | |
+ +---<---+ | +--------------->-----------|----+
+ | | | |
+ | | +---------------+ |
+ | ______v___ ______ | _______________v_______________
+ | / default: read \ | / ROWID-ORDERED RETRIEVAL: \
+ | | table records | | | Before reading table records, |
+ v | in random order | v | sort their rowids and then |
+ | \_________________/ | | read them in rowid order |
+ | | | \_______________________________/
+ | | | |
+ | | | |
+ +-->---+ | +----<------+-----------<--------+
+ | | |
+ v v v
+ (table records and range_ids)
+
+ The choice of strategy depends on MRR scan properties, table properties
+ (whether we're scanning clustered primary key), and @@optimizer_switch
+ settings.
+
+ Key-Ordered Retrieval
+ ---------------------
+ The idea is: if MRR scan is essentially a series of lookups on
+
+ tbl.key=value1 OR tbl.key=value2 OR ... OR tbl.key=valueN
+
+ then it makes sense to collect and order the set of lookup values, i.e.
+
+ sort(value1, value2, .. valueN)
+
+ and then do index lookups in index order. This results in fewer index page
+ fetch operations, and we also can avoid making multiple index lookups for the
+ same value. That is, if value1=valueN we can easily discover that after
+ sorting and make one index lookup for them instead of two.
+
+ Rowid-Ordered Retrieval
+ -----------------------
+ If we do a regular index scan or a series of index lookups, we'll be hitting
+ table records at random. For disk-based engines, this is much slower than
+ reading the same records in disk order. We assume that disk ordering of
+ rows is the same as ordering of their rowids (which is provided by
+ handler::cmp_ref())
+ In order to retrieve records in different order, we must separate index
+ scanning and record fetching, that is, MRR scan uses the following steps:
+
+ 1. Scan the index (and only index, that is, with HA_EXTRA_KEYREAD on) and
+ fill a buffer with {rowid, range_id} pairs
+ 2. Sort the buffer by rowid value
+ 3. for each {rowid, range_id} pair in the buffer
+ get record by rowid and return the {record, range_id} pair
+ 4. Repeat the above steps until we've exhausted the list of ranges we're
+ scanning.
+
+ Buffer space management considerations
+ --------------------------------------
+ With regards to buffer/memory management, MRR interface specifies that
+ - SQL layer provides multi_range_read_init() with buffer of certain size.
+ - MRR implementation may use (i.e. have at its disposal till the end of
+ the MRR scan) all of the buffer, or return the unused end of the buffer
+ to SQL layer.
+
+ DS-MRR needs buffer in order to accumulate and sort rowids and/or keys. When
+ we need to accumulate/sort only keys (or only rowids), it is fairly trivial.
+
+ When we need to accumulate/sort both keys and rowids, efficient buffer use
+ gets complicated. We need to:
+ - First, accumulate keys and sort them
+ - Then use the keys (smaller values go first) to obtain rowids. A key is not
+ needed after we've got matching rowids for it.
+ - Make sure that rowids are accumulated at the front of the buffer, so that we
+ can return the end part of the buffer to SQL layer, should there be too
+ few rowid values to occupy the buffer.
+
+ All of these goals are achieved by using the following scheme:
+
+ | | We get an empty buffer from SQL layer.
+
+ | *-|
+ | *----| First, we fill the buffer with keys. Key_buffer
+ | *-------| part grows from end of the buffer space to start
+ | *----------| (In this picture, the buffer is big enough to
+ | *-------------| accomodate all keys and even have some space left)
+
+ | *=============| We want to do key-ordered index scan, so we sort
+ the keys
+
+ |-x *===========| Then we use the keys get rowids. Rowids are
+ |----x *========| stored from start of buffer space towards the end.
+ |--------x *=====| The part of the buffer occupied with keys
+ |------------x *===| gradually frees up space for rowids. In this
+ |--------------x *=| picture we run out of keys before we've ran out
+ |----------------x | of buffer space (it can be other way as well).
+
+ |================x | Then we sort the rowids.
+
+ | |~~~| The unused part of the buffer is at the end, so
+ we can return it to the SQL layer.
+
+ |================* Sorted rowids are then used to read table records
+ in disk order
+
+*/
+
+class DsMrr_impl
+{
+public:
+ typedef void (handler::*range_check_toggle_func_t)(bool on);
+
+ DsMrr_impl()
+ : secondary_file(NULL) {};
+
+ void init(handler *h_arg, TABLE *table_arg)
+ {
+ primary_file= h_arg;
+ table= table_arg;
+ }
+ int dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
+ void *seq_init_param, uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf);
+ void dsmrr_close();
+ int dsmrr_next(char **range_info);
+
+ ha_rows dsmrr_info(uint keyno, uint n_ranges, uint keys, uint key_parts,
+ uint *bufsz, uint *flags, COST_VECT *cost);
+
+ ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param, uint n_ranges, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+private:
+ /* Buffer to store (key, range_id) pairs */
+ Lifo_buffer *key_buffer;
+
+ /*
+ The "owner" handler object (the one that is expected to "own" this object
+ and call its functions).
+ */
+ handler *primary_file;
+ TABLE *table; /* Always equal to primary_file->table */
+
+ /*
+ Secondary handler object. (created when needed, we need it when we need
+ to run both index scan and rnd_pos() scan at the same time)
+ */
+ handler *secondary_file;
+
+ uint keyno; /* index we're running the scan on */
+ /* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
+ bool is_mrr_assoc;
+
+ Mrr_reader_factory reader_factory;
+
+ Mrr_reader *strategy;
+ bool strategy_exhausted;
+
+ Mrr_index_reader *index_strategy;
+
+ /* The whole buffer space that we're using */
+ uchar *full_buf;
+ uchar *full_buf_end;
+
+ /*
+ When using both rowid and key buffers: the boundary between key and rowid
+ parts of the buffer. This is the "original" value, actual memory ranges
+ used by key and rowid parts may be different because of dynamic space
+ reallocation between them.
+ */
+ uchar *rowid_buffer_end;
+
+ /*
+ One of the following two is used for key buffer: forward is used when
+ we only need key buffer, backward is used when we need both key and rowid
+ buffers.
+ */
+ Forward_lifo_buffer forward_key_buf;
+ Backward_lifo_buffer backward_key_buf;
+
+ /*
+ Buffer to store (rowid, range_id) pairs, or just rowids if
+ is_mrr_assoc==FALSE
+ */
+ Forward_lifo_buffer rowid_buffer;
+
+ bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz,
+ COST_VECT *cost);
+ bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
+ uint *buffer_size, COST_VECT *cost);
+ bool check_cpk_scan(THD *thd, uint keyno, uint mrr_flags);
+
+ bool setup_buffer_sharing(uint key_size_in_keybuf, key_part_map key_tuple_map);
+
+ /* Buffer_manager and its member functions */
+ Buffer_manager buf_manager;
+ static void redistribute_buffer_space(void *dsmrr_arg);
+ static void reset_buffer_sizes(void *dsmrr_arg);
+ static void do_nothing(void *dsmrr_arg);
+
+ Lifo_buffer* get_key_buffer() { return key_buffer; }
+
+ friend class Key_value_records_iterator;
+ friend class Mrr_ordered_index_reader;
+ friend class Mrr_ordered_rndpos_reader;
+
+ int setup_two_handlers();
+ void close_second_handler();
+};
+
+/**
+ @} (end of group DS-MRR declarations)
+*/
+
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3f836a5ab1f..d75a330b75f 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -360,11 +360,11 @@ protected:
The cost of average seek
DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*BLOCKS_IN_AVG_SEEK =1.0.
*/
-#define DISK_SEEK_BASE_COST ((double)0.5)
+#define DISK_SEEK_BASE_COST ((double)0.9)
#define BLOCKS_IN_AVG_SEEK 128
-#define DISK_SEEK_PROP_COST ((double)0.5/BLOCKS_IN_AVG_SEEK)
+#define DISK_SEEK_PROP_COST ((double)0.1/BLOCKS_IN_AVG_SEEK)
/**
@@ -374,6 +374,12 @@ protected:
*/
#define MATCHING_ROWS_IN_OTHER_TABLE 10
+/*
+ Subquery materialization-related constants
+*/
+#define HEAP_TEMPTABLE_LOOKUP_COST 0.05
+#define DISK_TEMPTABLE_LOOKUP_COST 1.0
+
/** Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used). */
#define KEY_DEFAULT_PACK_LENGTH 8
@@ -555,12 +561,27 @@ protected:
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
+#define OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN 16
+
+#define OPTIMIZER_SWITCH_FIRSTMATCH 32
+#define OPTIMIZER_SWITCH_LOOSE_SCAN 64
+#define OPTIMIZER_SWITCH_MATERIALIZATION 128
+#define OPTIMIZER_SWITCH_SEMIJOIN 256
+#define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE 512
+#define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN 1024
+#define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1<<11)
+#define OPTIMIZER_SWITCH_MRR_SORT_KEYS (1<<12)
+#define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1<<13)
+#define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1<<14)
+#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1<<15)
+#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1<<16)
+#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1<<17)
#ifdef DBUG_OFF
-# define OPTIMIZER_SWITCH_LAST 16
+# define OPTIMIZER_SWITCH_LAST (1<<18)
#else
-# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16
-# define OPTIMIZER_SWITCH_LAST 32
+# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1<<18)
+# define OPTIMIZER_SWITCH_LAST (1<<19)
#endif
#ifdef DBUG_OFF
@@ -568,13 +589,38 @@ protected:
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
-#else
+ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
+ OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
+ OPTIMIZER_SWITCH_FIRSTMATCH | \
+ OPTIMIZER_SWITCH_LOOSE_SCAN | \
+ OPTIMIZER_SWITCH_MATERIALIZATION | \
+ OPTIMIZER_SWITCH_SEMIJOIN | \
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
+ OPTIMIZER_SWITCH_SUBQUERY_CACHE|\
+ OPTIMIZER_SWITCH_MRR_SORT_KEYS|\
+ OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_BKA)
+#else
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
- OPTIMIZER_SWITCH_TABLE_ELIMINATION)
+ OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
+ OPTIMIZER_SWITCH_TABLE_ELIMINATION | \
+ OPTIMIZER_SWITCH_FIRSTMATCH | \
+ OPTIMIZER_SWITCH_LOOSE_SCAN | \
+ OPTIMIZER_SWITCH_MATERIALIZATION | \
+ OPTIMIZER_SWITCH_SEMIJOIN | \
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
+ OPTIMIZER_SWITCH_SUBQUERY_CACHE|\
+ OPTIMIZER_SWITCH_MRR_SORT_KEYS|\
+ OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_BKA)
#endif
/*
@@ -654,7 +700,8 @@ enum enum_parsing_place
SELECT_LIST,
IN_WHERE,
IN_ON,
- IN_GROUP_BY
+ IN_GROUP_BY,
+ PARSING_PLACE_SIZE /* always should be the last */
};
struct st_table;
@@ -853,6 +900,7 @@ bool general_log_write(THD *thd, enum enum_server_command command,
#ifdef MYSQL_SERVER
#include "sql_servers.h"
#include "opt_range.h"
+#include "sql_expression_cache.h"
#ifdef HAVE_QUERY_CACHE
struct Query_cache_query_flags
@@ -1187,6 +1235,9 @@ bool mysql_select(THD *thd, Item ***rref_pointer_array,
Item *having, ORDER *proc_param, ulonglong select_type,
select_result *result, SELECT_LEX_UNIT *unit,
SELECT_LEX *select_lex);
+
+int join_read_key2(THD *thd, struct st_join_table *tab, TABLE *table,
+ struct st_table_ref *table_ref);
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
select_result *result);
@@ -1206,6 +1257,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
bool table_cant_handle_bit_fields,
bool make_copy_field,
uint convert_blob_length);
+bool open_tmp_table(TABLE *table);
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
int prepare_create_field(Create_field *sql_field,
uint *blob_columns,
@@ -1435,15 +1487,6 @@ void mysqld_stmt_reset(THD *thd, char *packet);
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
void reinit_stmt_before_use(THD *thd, LEX *lex);
-/* sql_handler.cc */
-bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
-bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
-bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
- List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
-void mysql_ha_flush(THD *thd);
-void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables, bool is_locked);
-void mysql_ha_cleanup(THD *thd);
-
/* sql_base.cc */
#define TMP_TABLE_KEY_EXTRA 8
void set_item_name(Item *item,char *pos,uint length);
@@ -1762,7 +1805,7 @@ bool close_cached_connection_tables(THD *thd, bool wait_for_refresh,
bool have_lock = FALSE);
void copy_field_from_tmp_record(Field *field,int offset);
bool fill_record(THD *thd, Field **field, List<Item> &values,
- bool ignore_errors);
+ bool ignore_errors, bool use_value);
bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
List<Item> &values,
bool ignore_errors,
@@ -1817,6 +1860,8 @@ void print_cached_tables(void);
void TEST_filesort(SORT_FIELD *sortorder,uint s_length);
void print_plan(JOIN* join,uint idx, double record_count, double read_time,
double current_read_time, const char *info);
+void print_keyuse_array(DYNAMIC_ARRAY *keyuse_array);
+void print_sjm(SJ_MATERIALIZATION_INFO *sjm);
#endif
void mysql_print_status();
/* key.cc */
@@ -1829,7 +1874,11 @@ bool key_cmp_if_same(TABLE *form,const uchar *key,uint index,uint key_length);
void key_unpack(String *to,TABLE *form,uint index);
bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields);
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length);
+ulong key_hashnr(KEY *key_info, uint used_key_parts, const uchar *key);
+bool key_buf_cmp(KEY *key_info, uint used_key_parts,
+ const uchar *key1, const uchar *key2);
extern "C" int key_rec_cmp(void *key_info, uchar *a, uchar *b);
+int key_tuple_cmp(KEY_PART_INFO *part, uchar *key1, uchar *key2, uint tuple_length);
bool init_errmessage(void);
#endif /* MYSQL_SERVER */
@@ -2136,6 +2185,10 @@ extern struct st_VioSSLFd * ssl_acceptor_fd;
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
uint flags, bool *need_reopen);
+bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock,
+ bool write_lock_used,
+ uint flags, bool *need_reopen);
+
/* mysql_lock_tables() and open_table() flags bits */
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001
#define MYSQL_LOCK_IGNORE_FLUSH 0x0002
@@ -2143,8 +2196,12 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
#define MYSQL_OPEN_TEMPORARY_ONLY 0x0008
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY 0x0010
#define MYSQL_LOCK_PERF_SCHEMA 0x0020
+#define MYSQL_LOCK_NOT_TEMPORARY 0x0040
+/* flags for get_lock_data */
+#define GET_LOCK_UNLOCK 1
+#define GET_LOCK_STORE_LOCKS 2
-void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
+void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock= 1);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
@@ -2156,6 +2213,7 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
TABLE_LIST *haystack);
+void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock);
bool lock_global_read_lock(THD *thd);
void unlock_global_read_lock(THD *thd);
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
@@ -2165,6 +2223,8 @@ bool make_global_read_lock_block_commit(THD *thd);
bool set_protect_against_global_read_lock(void);
void unset_protect_against_global_read_lock(void);
void broadcast_refresh(void);
+MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
+ uint flags, TABLE **write_lock_used);
/* Lock based on name */
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
@@ -2495,6 +2555,19 @@ inline bool is_user_table(TABLE * table)
return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
}
+
+#ifndef HAVE_LOG2
+/*
+ This will be slightly slower and perhaps a tiny bit less accurate than
+ doing it the IEEE754 way but log2() should be available on C99 systems.
+*/
+inline double log2(double x)
+{
+ return (log(x) / M_LN2);
+}
+#endif
+
+
/*
Some functions that are different in the embedded library and the normal
server
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 3d6879e5b23..c086c34a39a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -340,6 +340,17 @@ static const char *optimizer_switch_names[]=
{
"index_merge","index_merge_union","index_merge_sort_union",
"index_merge_intersection",
+ "index_condition_pushdown",
+ "firstmatch","loosescan","materialization", "semijoin",
+ "partial_match_rowid_merge",
+ "partial_match_table_scan",
+ "subquery_cache",
+ "mrr_sort_keys",
+ "outer_join_with_cache",
+ "semijoin_with_cache",
+ "join_cache_incremental",
+ "join_cache_hashed",
+ "join_cache_bka",
#ifndef DBUG_OFF
"table_elimination",
#endif
@@ -353,6 +364,20 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("index_merge_union") - 1,
sizeof("index_merge_sort_union") - 1,
sizeof("index_merge_intersection") - 1,
+ sizeof("index_condition_pushdown") - 1,
+ sizeof("firstmatch") - 1,
+ sizeof("loosescan") - 1,
+ sizeof("materialization") - 1,
+ sizeof("semijoin") - 1,
+ sizeof("partial_match_rowid_merge") - 1,
+ sizeof("partial_match_table_scan") - 1,
+ sizeof("subquery_cache") - 1,
+ sizeof("mrr_sort_keys") - 1,
+ sizeof("outer_join_with_cache") - 1,
+ sizeof("semijoin_with_cache") - 1,
+ sizeof("join_cache_incremental") - 1,
+ sizeof("join_cache_hashed") - 1,
+ sizeof("join_cache_bka") - 1,
#ifndef DBUG_OFF
sizeof("table_elimination") - 1,
#endif
@@ -432,7 +457,7 @@ static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
static my_bool opt_ignore_wrong_options= 0, opt_expect_abort= 0;
-static my_bool opt_sync= 0;
+static my_bool opt_sync= 0, opt_thread_alarm;
static uint kill_cached_threads, wake_thread;
ulong thread_created;
uint thread_handling;
@@ -443,8 +468,20 @@ static const char *sql_mode_str= "OFF";
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"index_merge_sort_union=on,"
- "index_merge_intersection=on"
-#ifndef DBUG_OFF
+ "index_merge_intersection=on,"
+ "index_condition_pushdown=on,"
+ "firstmatch=on,"
+ "loosescan=on,"
+ "materialization=on,"
+ "semijoin=on,"
+ "partial_match_rowid_merge=on,"
+ "partial_match_table_scan=on,"
+ "subquery_cache=on,"
+ "mrr_sort_keys=on,"
+ "join_cache_incremental=on,"
+ "join_cache_hashed=on,"
+ "join_cache_bka=on"
+#ifndef DBUG_OFF
",table_elimination=on";
#else
;
@@ -3652,6 +3689,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
global_system_variables.character_set_results= default_charset_info;
global_system_variables.character_set_client= default_charset_info;
+ global_system_variables.optimizer_use_mrr= 1;
+
if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
MY_CS_PRIMARY, MYF(MY_WME))))
@@ -5917,6 +5956,7 @@ enum options_mysqld
OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
+ OPT_JOIN_BUFF_SPACE_LIMIT, OPT_JOIN_CACHE_LEVEL,
OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
OPT_KEY_CACHE_PARTITIONS,
@@ -5930,7 +5970,7 @@ enum options_mysqld
OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
OPT_MAX_LENGTH_FOR_SORT_DATA,
OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
- OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
+ OPT_MAX_ERROR_COUNT, OPT_MRR_BUFFER_SIZE, OPT_MYISAM_DATA_POINTER_SIZE,
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
@@ -5950,7 +5990,10 @@ enum options_mysqld
OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
OPT_RELAY_LOG_PURGE,
OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
- OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING, OPT_DEBUG_FLUSH,
+ OPT_SLAVE_TRANS_RETRIES,
+ OPT_SUBQUERY_CACHE,
+ OPT_READONLY, OPT_ROWID_MERGE_BUFF_SIZE,
+ OPT_DEBUGGING, OPT_DEBUG_FLUSH,
OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
@@ -5960,7 +6003,7 @@ enum options_mysqld
OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
- OPT_SYNC_FRM, OPT_SYNC_BINLOG, OPT_SYNC,
+ OPT_SYNC_FRM, OPT_SYNC_BINLOG, OPT_SYNC, OPT_THREAD_ALARM,
OPT_SYNC_REPLICATION,
OPT_SYNC_REPLICATION_SLAVE_ID,
OPT_SYNC_REPLICATION_TIMEOUT,
@@ -6285,7 +6328,7 @@ struct my_option my_long_options[] =
"Disable initialization of builtin InnoDB plugin.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"init-connect", OPT_INIT_CONNECT,
- "Command(s) that are executed for each new connection.",
+ "Command(s) that are executed for each new connection (but not for SUPER users).",
&opt_init_connect, &opt_init_connect, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DISABLE_GRANT_OPTIONS
@@ -7061,11 +7104,22 @@ thread is in the relay logs.",
&max_system_variables.net_interactive_timeout, 0,
GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
{"join_buffer_size", OPT_JOIN_BUFF_SIZE,
- "The size of the buffer that is used for full joins.",
- &global_system_variables.join_buff_size,
- &max_system_variables.join_buff_size, 0, GET_ULONG,
- REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, (longlong) ULONG_MAX,
- MALLOC_OVERHEAD, IO_SIZE, 0},
+ "The size of the buffer that is used for joins.",
+ &global_system_variables.join_buff_size,
+ &max_system_variables.join_buff_size, 0, GET_ULONG,
+ REQUIRED_ARG, 128*1024L, 128+MALLOC_OVERHEAD, (longlong) ULONG_MAX,
+ MALLOC_OVERHEAD, 128, 0},
+ {"join_buffer_space_limit", OPT_JOIN_BUFF_SPACE_LIMIT,
+ "The limit of the space for all join buffers used by a query.",
+ &global_system_variables.join_buff_space_limit,
+ &max_system_variables.join_buff_space_limit, 0, GET_ULL,
+ REQUIRED_ARG, 8*128*1024L, 2048+MALLOC_OVERHEAD, (longlong) ULONGLONG_MAX,
+ MALLOC_OVERHEAD, 2048, 0},
+ {"join_cache_level", OPT_JOIN_CACHE_LEVEL,
+ "Controls what join operations can be executed with join buffers. Odd numbers are used for plain join buffers while even numbers are used for linked buffers",
+ &global_system_variables.join_cache_level,
+ &max_system_variables.join_cache_level,
+ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 8, 0, 1, 0},
{"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
"Don't overwrite stale .MYD and .MYI even if no directory is specified.",
&global_system_variables.keep_files_on_create,
@@ -7238,11 +7292,12 @@ thread is in the relay logs.",
&global_system_variables.min_examined_row_limit,
&max_system_variables.min_examined_row_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1L, 0},
- {"multi_range_count", OPT_MULTI_RANGE_COUNT,
- "Number of key ranges to request at once.",
- &global_system_variables.multi_range_count,
- &max_system_variables.multi_range_count, 0,
- GET_ULONG, REQUIRED_ARG, 256, 1, (longlong) ULONG_MAX, 0, 1, 0},
+ {"mrr_buffer_size", OPT_MRR_BUFFER_SIZE,
+ "Size of buffer to use when using MRR with range access",
+ (uchar**) &global_system_variables.mrr_buff_size,
+ (uchar**) &max_system_variables.mrr_buff_size, 0,
+ GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
+ INT_MAX32, MALLOC_OVERHEAD, 1 /* Small to be able to do tests */ , 0},
{"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
"Block size to be used for MyISAM index pages.",
&opt_myisam_block_size, &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
@@ -7348,7 +7403,11 @@ thread is in the relay logs.",
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
{"optimizer_switch", OPT_OPTIMIZER_SWITCH,
"optimizer_switch=option=val[,option=val...], where option={index_merge, "
- "index_merge_union, index_merge_sort_union, index_merge_intersection"
+ "index_merge_union, index_merge_sort_union, index_merge_intersection, "
+ "index_condition_pushdown, firstmatch, loosescan, materialization, "
+ "semijoin, partial_match_rowid_merge, partial_match_table_scan, "
+ "subquery_cache, outer_join_with_cache, semijoin_with_cache, "
+ "join_cache_incremental, join_cache_hashed, join_cache_bka"
#ifndef DBUG_OFF
", table_elimination"
#endif
@@ -7421,6 +7480,11 @@ thread is in the relay logs.",
&max_system_variables.range_alloc_block_size, 0, GET_ULONG,
REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE,
(longlong) ULONG_MAX, 0, 1024, 0},
+ {"rowid_merge_buff_size", OPT_ROWID_MERGE_BUFF_SIZE,
+ "The size of the buffers used [NOT] IN evaluation via partial matching.",
+ (uchar**) &global_system_variables.rowid_merge_buff_size,
+ (uchar**) &max_system_variables.rowid_merge_buff_size, 0, GET_ULONG,
+ REQUIRED_ARG, 8*1024*1024L, 0, MAX_MEM_TABLE_SIZE/2, 0, 1, 0},
{"read_buffer_size", OPT_RECORD_BUFFER,
"Each thread that does a sequential scan allocates a buffer of this size "
"for each table it scans. If you do many sequential scans, you may want "
@@ -7515,6 +7579,10 @@ thread is in the relay logs.",
"error. Used only if the connection has active cursors.",
&table_lock_wait_timeout, &table_lock_wait_timeout,
0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
+ {"thread-alarm", OPT_THREAD_ALARM,
+ "Enable/disable system thread alarm calls. Should only be turned off when running tests or debugging!!",
+ &opt_thread_alarm, &opt_thread_alarm, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
+ 0},
{"thread_cache_size", OPT_THREAD_CACHE_SIZE,
"How many threads we should keep in a cache for reuse.",
&thread_cache_size, &thread_cache_size, 0, GET_ULONG,
@@ -8052,8 +8120,8 @@ SHOW_VAR status_vars[]= {
{"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
{"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
{"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
- {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONG_STATUS},
- {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONG_STATUS},
+ {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
+ {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
#ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@@ -8111,6 +8179,12 @@ SHOW_VAR status_vars[]= {
{"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC},
#endif /* HAVE_OPENSSL */
{"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH},
+ /*
+ Expression cache used only for caching subqueries now, so its statistic
+ variables we call subquery_cache*.
+ */
+ {"Subquery_cache_hit", (char*) &subquery_cache_hit, SHOW_LONG},
+ {"Subquery_cache_miss", (char*) &subquery_cache_miss, SHOW_LONG},
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
#ifdef HAVE_MMAP
@@ -8250,6 +8324,7 @@ static int mysql_init_variables(void)
abort_loop= select_thread_in_use= signal_thread_in_use= 0;
ready_to_exit= shutdown_in_progress= grant_option= 0;
aborted_threads= aborted_connects= 0;
+ subquery_cache_miss= subquery_cache_hit= 0;
delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
delayed_insert_errors= thread_created= 0;
specialflag= 0;
@@ -9287,6 +9362,7 @@ static int get_options(int *argc,char **argv)
*/
my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
my_disable_sync= opt_sync == 0;
+ my_disable_thr_alarm= opt_thread_alarm == 0;
my_default_record_cache_size=global_system_variables.read_buff_size;
myisam_max_temp_length=
(my_off_t) global_system_variables.myisam_max_sort_file_size;
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index ff426a4a608..1b313da8ce1 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -116,7 +116,7 @@ my_bool my_net_init(NET *net, Vio* vio)
net->vio = vio;
my_net_local_init(net); /* Set some limits */
if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+
- NET_HEADER_SIZE + COMP_HEADER_SIZE,
+ NET_HEADER_SIZE + COMP_HEADER_SIZE +1,
MYF(MY_WME))))
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
@@ -268,18 +268,20 @@ static int net_data_is_ready(my_socket sd)
#endif /* EMBEDDED_LIBRARY */
/**
- Remove unwanted characters from connection
- and check if disconnected.
+ Intialize NET handler for new reads:
- Read from socket until there is nothing more to read. Discard
- what is read.
+ - Read from socket until there is nothing more to read. Discard
+ what is read.
+ - Initialize net for new net_read/net_write calls.
- If there is anything when to read 'net_clear' is called this
- normally indicates an error in the protocol.
+ If there is anything when to read 'net_clear' is called this
+ normally indicates an error in the protocol. Normally one should not
+ need to do clear the communication buffer. If one compiles without
+ -DUSE_NET_CLEAR then one wins one read call / query.
- When connection is properly closed (for TCP it means with
- a FIN packet), then select() considers a socket "ready to read",
- in the sense that there's EOF to read, but read() returns 0.
+ When connection is properly closed (for TCP it means with
+ a FIN packet), then select() considers a socket "ready to read",
+ in the sense that there's EOF to read, but read() returns 0.
@param net NET handler
@param clear_buffer if <> 0, then clear all data from comm buff
@@ -287,20 +289,18 @@ static int net_data_is_ready(my_socket sd)
void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
-#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
- size_t count;
- int ready;
-#endif
DBUG_ENTER("net_clear");
/*
- We don't do a clear in case of DBUG_OFF to catch bugs
- in the protocol handling
+ We don't do a clear in case of not DBUG_OFF to catch bugs in the
+ protocol handling.
*/
-#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
+#if (!defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)) || defined(USE_NET_CLEAR)
if (clear_buffer)
{
+ size_t count;
+ int ready;
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
{
/* The socket is ready */
@@ -590,7 +590,7 @@ net_real_write(NET *net,const uchar *packet, size_t len)
uchar *b;
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
- COMP_HEADER_SIZE, MYF(MY_WME))))
+ COMP_HEADER_SIZE + 1, MYF(MY_WME))))
{
net->error= 2;
net->last_errno= ER_OUT_OF_RESOURCES;
@@ -697,7 +697,8 @@ net_real_write(NET *net,const uchar *packet, size_t len)
{
my_bool old_mode;
thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking, &old_mode);
+ if (!net_blocking)
+ vio_blocking(net->vio, net_blocking, &old_mode);
}
net->reading_or_writing=0;
DBUG_RETURN(((int) (pos != end)));
@@ -988,7 +989,8 @@ end:
{
my_bool old_mode;
thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking, &old_mode);
+ if (!net_blocking)
+ vio_blocking(net->vio, net_blocking, &old_mode);
}
net->reading_or_writing=0;
#ifdef DEBUG_DATA_PACKETS
diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc
new file mode 100644
index 00000000000..9f6cd69663d
--- /dev/null
+++ b/sql/opt_index_cond_pushdown.cc
@@ -0,0 +1,399 @@
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+/****************************************************************************
+ * Index Condition Pushdown code starts
+ ***************************************************************************/
+/*
+ Check if given expression uses only table fields covered by the given index
+
+ SYNOPSIS
+ uses_index_fields_only()
+ item Expression to check
+ tbl The table having the index
+ keyno The index number
+ other_tbls_ok TRUE <=> Fields of other non-const tables are allowed
+
+ DESCRIPTION
+ Check if given expression only uses fields covered by index #keyno in the
+ table tbl. The expression can use any fields in any other tables.
+
+ The expression is guaranteed not to be AND or OR - those constructs are
+ handled outside of this function.
+
+ RETURN
+ TRUE Yes
+ FALSE No
+*/
+
+bool uses_index_fields_only(Item *item, TABLE *tbl, uint keyno,
+ bool other_tbls_ok)
+{
+ if (item->const_item())
+ return TRUE;
+
+ /*
+ Don't push down the triggered conditions. Nested outer joins execution
+ code may need to evaluate a condition several times (both triggered and
+ untriggered), and there is no way to put thi
+ TODO: Consider cloning the triggered condition and using the copies for:
+ 1. push the first copy down, to have most restrictive index condition
+ possible
+ 2. Put the second copy into tab->select_cond.
+ */
+ if (item->type() == Item::FUNC_ITEM &&
+ ((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
+ return FALSE;
+
+ if (!(item->used_tables() & tbl->map))
+ return other_tbls_ok;
+
+ Item::Type item_type= item->type();
+ switch (item_type) {
+ case Item::FUNC_ITEM:
+ {
+ /* This is a function, apply condition recursively to arguments */
+ Item_func *item_func= (Item_func*)item;
+ Item **child;
+ Item **item_end= (item_func->arguments()) + item_func->argument_count();
+ for (child= item_func->arguments(); child != item_end; child++)
+ {
+ if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case Item::COND_ITEM:
+ {
+ /*
+ This is a AND/OR condition. Regular AND/OR clauses are handled by
+ make_cond_for_index() which will chop off the part that can be
+ checked with index. This code is for handling non-top-level AND/ORs,
+ e.g. func(x AND y).
+ */
+ List_iterator<Item> li(*((Item_cond*)item)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case Item::FIELD_ITEM:
+ {
+ Item_field *item_field= (Item_field*)item;
+ if (item_field->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;
+ }
+ case Item::REF_ITEM:
+ return uses_index_fields_only(item->real_item(), tbl, keyno,
+ other_tbls_ok);
+ default:
+ return FALSE; /* Play it safe, don't push unknown non-const items */
+ }
+}
+
+#define ICP_COND_USES_INDEX_ONLY 10
+
+/*
+ Get a part of the condition that can be checked using only index fields
+
+ SYNOPSIS
+ make_cond_for_index()
+ cond The source condition
+ table The table that is partially available
+ keyno The index in the above table. Only fields covered by the index
+ are available
+ other_tbls_ok TRUE <=> Fields of other non-const tables are allowed
+
+ DESCRIPTION
+ Get a part of the condition that can be checked when for the given table
+ we have values only of fields covered by some index. The condition may
+ refer to other tables, it is assumed that we have values of all of their
+ fields.
+
+ Example:
+ make_cond_for_index(
+ "cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
+ t2, keyno(t2.key1))
+ will return
+ "cond(t1.field) AND cond(t2.key2)"
+
+ RETURN
+ Index condition, or NULL if no condition could be inferred.
+*/
+
+Item *make_cond_for_index(Item *cond, TABLE *table, uint keyno,
+ bool other_tbls_ok)
+{
+ if (!cond)
+ return NULL;
+ if (cond->type() == Item::COND_ITEM)
+ {
+ uint n_marked= 0;
+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
+ {
+ table_map used_tables= 0;
+ Item_cond_and *new_cond=new Item_cond_and;
+ if (!new_cond)
+ return (COND*) 0;
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
+ if (fix)
+ {
+ new_cond->argument_list()->push_back(fix);
+ used_tables|= fix->used_tables();
+ }
+ if (test(item->marker == ICP_COND_USES_INDEX_ONLY))
+ {
+ n_marked++;
+ item->marker= 0;
+ }
+ }
+ if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
+ cond->marker= ICP_COND_USES_INDEX_ONLY;
+ switch (new_cond->argument_list()->elements) {
+ case 0:
+ return (COND*) 0;
+ case 1:
+ new_cond->used_tables_cache= used_tables;
+ return new_cond->argument_list()->head();
+ default:
+ new_cond->quick_fix_field();
+ new_cond->used_tables_cache= used_tables;
+ return new_cond;
+ }
+ }
+ else /* It's OR */
+ {
+ Item_cond_or *new_cond=new Item_cond_or;
+ if (!new_cond)
+ return (COND*) 0;
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
+ if (!fix)
+ return (COND*) 0;
+ new_cond->argument_list()->push_back(fix);
+ if (test(item->marker == ICP_COND_USES_INDEX_ONLY))
+ {
+ n_marked++;
+ item->marker= 0;
+ }
+ }
+ if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
+ cond->marker= ICP_COND_USES_INDEX_ONLY;
+ new_cond->quick_fix_field();
+ new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
+ new_cond->top_level_item();
+ return new_cond;
+ }
+ }
+
+ if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
+ return (COND*) 0;
+ cond->marker= ICP_COND_USES_INDEX_ONLY;
+ return cond;
+}
+
+
+Item *make_cond_remainder(Item *cond, 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;
+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
+ {
+ /* Create new top level AND item */
+ Item_cond_and *new_cond=new Item_cond_and;
+ if (!new_cond)
+ return (COND*) 0;
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ Item *fix= make_cond_remainder(item, exclude_index);
+ if (fix)
+ {
+ new_cond->argument_list()->push_back(fix);
+ tbl_map |= fix->used_tables();
+ }
+ }
+ switch (new_cond->argument_list()->elements) {
+ case 0:
+ return (COND*) 0;
+ case 1:
+ return new_cond->argument_list()->head();
+ default:
+ new_cond->quick_fix_field();
+ ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
+ return new_cond;
+ }
+ }
+ else /* It's OR */
+ {
+ Item_cond_or *new_cond=new Item_cond_or;
+ if (!new_cond)
+ return (COND*) 0;
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ Item *fix= make_cond_remainder(item, FALSE);
+ if (!fix)
+ return (COND*) 0;
+ new_cond->argument_list()->push_back(fix);
+ tbl_map |= fix->used_tables();
+ }
+ new_cond->quick_fix_field();
+ ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
+ new_cond->top_level_item();
+ return new_cond;
+ }
+ }
+ return cond;
+}
+
+
+/*
+ Try to extract and push the index condition
+
+ SYNOPSIS
+ push_index_cond()
+ tab A join tab that has tab->table->file and its condition
+ in tab->select_cond
+ keyno Index for which extract and push the condition
+ other_tbls_ok TRUE <=> Fields of other non-const tables are allowed
+ factor_out TRUE <=> Factor out the extracted condition
+
+ DESCRIPTION
+ Try to extract and push the index condition down to table handler
+*/
+
+void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok,
+ bool factor_out)
+{
+ 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)
+ {
+ DBUG_EXECUTE("where",
+ print_where(tab->select_cond, "full cond", QT_ORDINARY););
+
+ idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
+ other_tbls_ok);
+
+ DBUG_EXECUTE("where",
+ print_where(idx_cond, "idx cond", QT_ORDINARY););
+
+ if (idx_cond)
+ {
+ Item *idx_remainder_cond= 0;
+ tab->pre_idx_push_select_cond= tab->select->cond;
+ /*
+ For BKA cache we store condition to special BKA cache field
+ because evaluation of the condition requires additional operations
+ before the evaluation. This condition is used in
+ JOIN_CACHE_BKA[_UNIQUE]::skip_index_tuple() functions.
+ */
+ if (tab->use_join_cache &&
+ /*
+ if cache is used then the value is TRUE only
+ for BKA[_UNIQUE] cache (see check_join_cache_usage func).
+ In this case other_tbls_ok is an equivalent of
+ cache->is_key_access().
+ */
+ other_tbls_ok &&
+ (idx_cond->used_tables() &
+ ~(tab->table->map | tab->join->const_table_map)))
+ tab->cache_idx_cond= idx_cond;
+ else
+ idx_remainder_cond= tab->table->file->idx_cond_push(keyno, idx_cond);
+
+ /*
+ Disable eq_ref's "lookup cache" if we've pushed down an index
+ condition.
+ TODO: This check happens to work on current ICP implementations, but
+ there may exist a compliant implementation that will not work
+ correctly with it. Sort this out when we stabilize the condition
+ pushdown APIs.
+ */
+ if (idx_remainder_cond != idx_cond)
+ tab->ref.disable_cache= TRUE;
+
+ Item *row_cond= factor_out ? make_cond_remainder(tab->select_cond, TRUE) :
+ tab->pre_idx_push_select_cond;
+
+ DBUG_EXECUTE("where",
+ print_where(row_cond, "remainder cond", QT_ORDINARY););
+
+ if (row_cond)
+ {
+ if (!idx_remainder_cond)
+ tab->select_cond= row_cond;
+ else
+ {
+ COND *new_cond= new Item_cond_and(row_cond, idx_remainder_cond);
+ tab->select_cond= new_cond;
+ tab->select_cond->quick_fix_field();
+ ((Item_cond_and*)tab->select_cond)->used_tables_cache=
+ row_cond->used_tables() | idx_remainder_cond->used_tables();
+ }
+ }
+ else
+ tab->select_cond= idx_remainder_cond;
+ if (tab->select)
+ {
+ DBUG_EXECUTE("where",
+ print_where(tab->select->cond,
+ "select_cond",
+ QT_ORDINARY););
+
+ tab->select->cond= tab->select_cond;
+ tab->select->pre_idx_push_select_cond= tab->pre_idx_push_select_cond;
+ }
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 5b4aa53bb91..7f70aeaece2 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -34,7 +34,7 @@
The lists are returned in form of complicated structure of interlinked
SEL_TREE/SEL_IMERGE/SEL_ARG objects.
- See check_quick_keys, find_used_partitions for examples of how to walk
+ See quick_range_seq_next, find_used_partitions for examples of how to walk
this structure.
All direct "users" of this module are located within this file, too.
@@ -59,6 +59,48 @@
Record retrieval code for range/index_merge/groupby-min-max.
Implementations of QUICK_*_SELECT classes.
+
+ KeyTupleFormat
+ ~~~~~~~~~~~~~~
+ The code in this file (and elsewhere) makes operations on key value tuples.
+ Those tuples are stored in the following format:
+
+ The tuple is a sequence of key part values. The length of key part value
+ depends only on its type (and not depends on the what value is stored)
+
+ KeyTuple: keypart1-data, keypart2-data, ...
+
+ The value of each keypart is stored in the following format:
+
+ keypart_data: [isnull_byte] keypart-value-bytes
+
+ If a keypart may have a NULL value (key_part->field->real_maybe_null() can
+ be used to check this), then the first byte is a NULL indicator with the
+ following valid values:
+ 1 - keypart has NULL value.
+ 0 - keypart has non-NULL value.
+
+ <questionable-statement> If isnull_byte==1 (NULL value), then the following
+ keypart->length bytes must be 0.
+ </questionable-statement>
+
+ keypart-value-bytes holds the value. Its format depends on the field type.
+ The length of keypart-value-bytes may or may not depend on the value being
+ stored. The default is that length is static and equal to
+ KEY_PART_INFO::length.
+
+ Key parts with (key_part_flag & HA_BLOB_PART) have length depending of the
+ value:
+
+ keypart-value-bytes: value_length value_bytes
+
+ The value_length part itself occupies HA_KEY_BLOB_LENGTH=2 bytes.
+
+ See key_copy() and key_restore() for code to move data between index tuple
+ and table record
+
+ CAUTION: the above description is only sergefp's understanding of the
+ subject and may omit some details.
*/
#ifdef USE_PRAGMA_IMPLEMENTATION
@@ -403,6 +445,7 @@ public:
/* returns a number of keypart values (0 or 1) appended to the key buffer */
int store_min(uint length, uchar **min_key,uint min_key_flag)
{
+ /* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
if ((min_flag & GEOM_FLAG) ||
(!(min_flag & NO_MIN_RANGE) &&
!(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
@@ -627,6 +670,11 @@ public:
*/
bool using_real_indexes;
+ /*
+ Aggressively remove "scans" that do not have conditions on first
+ keyparts. Such scans are usable when doing partition pruning but not
+ regular range optimization.
+ */
bool remove_jump_scans;
/*
@@ -634,8 +682,17 @@ public:
using_real_indexes==TRUE
*/
uint real_keynr[MAX_KEY];
+
+ /*
+ Used to store 'current key tuples', in both range analysis and
+ partitioning (list) analysis
+ */
+ uchar min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
+ max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
+
/* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
uint alloced_sel_args;
+ bool force_default_mrr;
};
class PARAM : public RANGE_OPT_PARAM
@@ -645,8 +702,6 @@ public:
longlong baseflag;
uint max_key_part, range_count;
- uchar min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
- max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
bool quick; // Don't calulate possible keys
uint fields_bitmap_size;
@@ -665,6 +720,7 @@ public:
uint8 first_null_comp; /* first null component if any, 0 - otherwise */
};
+
class TABLE_READ_PLAN;
class TRP_RANGE;
class TRP_ROR_INTERSECT;
@@ -683,15 +739,14 @@ static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts);
-static ha_rows check_quick_select(PARAM *param,uint index,SEL_ARG *key_tree,
- bool update_tbl_stats);
-static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
- uchar *min_key, uint min_key_flag, int,
- uchar *max_key, uint max_key_flag, int);
+static ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
+ SEL_ARG *tree, bool update_tbl_stats,
+ uint *mrr_flags, uint *bufsize,
+ COST_VECT *cost);
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
- SEL_ARG *key_tree,
- MEM_ROOT *alloc = NULL);
+ SEL_ARG *key_tree, uint mrr_flags,
+ uint mrr_buf_size, MEM_ROOT *alloc);
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
@@ -734,7 +789,9 @@ static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
static bool null_part_in_key(KEY_PART *key_part, const uchar *key,
uint length);
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
+static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts);
+#include "opt_range_mrr.cc"
/*
SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
@@ -1062,7 +1119,7 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
}
-SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
+SQL_SELECT::SQL_SELECT() :quick(0),cond(0),pre_idx_push_select_cond(NULL),free_cond(0)
{
quick_keys.clear_all(); needed_reg.clear_all();
my_b_clear(&file);
@@ -1096,25 +1153,22 @@ QUICK_SELECT_I::QUICK_SELECT_I()
{}
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
- bool no_alloc, MEM_ROOT *parent_alloc)
- :dont_free(0),doing_key_read(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0)
+ bool no_alloc, MEM_ROOT *parent_alloc,
+ bool *create_error)
+ :doing_key_read(0),/*error(0),*/free_file(0),/*in_range(0),*/cur_range(NULL),last_range(0),dont_free(0)
{
my_bitmap_map *bitmap;
DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
in_ror_merged_scan= 0;
- sorted= 0;
index= key_nr;
head= table;
key_part_info= head->key_info[index].key_part;
my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
/* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
- multi_range_bufsiz= thd->variables.read_rnd_buff_size;
- multi_range_count= thd->variables.multi_range_count;
- multi_range_length= 0;
- multi_range= NULL;
- multi_range_buff= NULL;
+ mrr_buf_size= thd->variables.mrr_buff_size;
+ mrr_buf_desc= NULL;
if (!no_alloc && !parent_alloc)
{
@@ -1129,12 +1183,12 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
save_read_set= head->read_set;
save_write_set= head->write_set;
- /* Allocate a bitmap for used columns */
+ /* Allocate a bitmap for used columns (Q: why not on MEM_ROOT?) */
if (!(bitmap= (my_bitmap_map*) my_malloc(head->s->column_bitmap_size,
MYF(MY_WME))))
{
column_bitmap.bitmap= 0;
- error= 1;
+ *create_error= 1;
}
else
bitmap_init(&column_bitmap, bitmap, head->s->fields, FALSE);
@@ -1142,6 +1196,20 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
}
+void QUICK_RANGE_SELECT::need_sorted_output()
+{
+ if (!(mrr_flags & HA_MRR_SORTED))
+ {
+ /*
+ Native implementation can't produce sorted output. We'll have to
+ switch to default
+ */
+ mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
+ }
+ mrr_flags |= HA_MRR_SORTED;
+}
+
+
int QUICK_RANGE_SELECT::init()
{
DBUG_ENTER("QUICK_RANGE_SELECT::init");
@@ -1184,8 +1252,7 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
my_free((char*) column_bitmap.bitmap, MYF(MY_ALLOW_ZERO_PTR));
}
head->column_bitmaps_set(save_read_set, save_write_set);
- x_free(multi_range);
- x_free(multi_range_buff);
+ x_free(mrr_buf_desc);
DBUG_VOID_RETURN;
}
@@ -1535,7 +1602,7 @@ int QUICK_ROR_UNION_SELECT::init()
DBUG_ENTER("QUICK_ROR_UNION_SELECT::init");
if (init_queue(&queue, quick_selects.elements, 0,
FALSE , QUICK_ROR_UNION_SELECT::queue_cmp,
- (void*) this))
+ (void*) this, 0, 0))
{
bzero(&queue, sizeof(QUEUE));
DBUG_RETURN(1);
@@ -1975,9 +2042,11 @@ class TRP_RANGE : public TABLE_READ_PLAN
public:
SEL_ARG *key; /* set of intervals to be used in "range" method retrieval */
uint key_idx; /* key number in PARAM::key */
+ uint mrr_flags;
+ uint mrr_buf_size;
- TRP_RANGE(SEL_ARG *key_arg, uint idx_arg)
- : key(key_arg), key_idx(idx_arg)
+ TRP_RANGE(SEL_ARG *key_arg, uint idx_arg, uint mrr_flags_arg)
+ : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
{}
virtual ~TRP_RANGE() {} /* Remove gcc warning */
@@ -1986,7 +2055,8 @@ public:
{
DBUG_ENTER("TRP_RANGE::make_quick");
QUICK_RANGE_SELECT *quick;
- if ((quick= get_quick_select(param, key_idx, key, parent_alloc)))
+ if ((quick= get_quick_select(param, key_idx, key, mrr_flags,
+ mrr_buf_size, parent_alloc)))
{
quick->records= records;
quick->read_time= read_cost;
@@ -2211,7 +2281,8 @@ static int fill_used_fields_bitmap(PARAM *param)
int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_map prev_tables,
- ha_rows limit, bool force_quick_range)
+ ha_rows limit, bool force_quick_range,
+ bool ordered_output)
{
uint idx;
double scan_time;
@@ -2269,6 +2340,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
param.imerge_cost_buff_size= 0;
param.using_real_indexes= TRUE;
param.remove_jump_scans= TRUE;
+ param.force_default_mrr= ordered_output;
thd->no_errors=1; // Don't warn about NULL
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
@@ -4808,11 +4880,12 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool update_tbl_stats,
double read_time)
{
- int idx;
+ uint idx;
SEL_ARG **key,**end, **key_to_read= NULL;
ha_rows UNINIT_VAR(best_records); /* protected by key_to_read */
+ uint UNINIT_VAR(best_mrr_flags), /* protected by key_to_read */
+ UNINIT_VAR(best_buf_size); /* protected by key_to_read */
TRP_RANGE* read_plan= NULL;
- bool pk_is_clustered= param->table->file->primary_key_is_clustered();
DBUG_ENTER("get_key_scans_params");
/*
Note that there may be trees that have type SEL_TREE::KEY but contain no
@@ -4823,64 +4896,40 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
"tree scans"););
tree->ror_scans_map.clear_all();
tree->n_ror_scans= 0;
- for (idx= 0,key=tree->keys, end=key+param->keys;
- key != end ;
- key++,idx++)
+ for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
{
- ha_rows found_records;
- double found_read_time;
if (*key)
{
+ ha_rows found_records;
+ COST_VECT cost;
+ double found_read_time;
+ uint mrr_flags, buf_size;
uint keynr= param->real_keynr[idx];
if ((*key)->type == SEL_ARG::MAYBE_KEY ||
(*key)->maybe_flag)
param->needed_reg->set_bit(keynr);
- bool read_index_only= index_read_must_be_used ? TRUE :
- (bool) param->table->covering_keys.is_set(keynr);
+ bool read_index_only= index_read_must_be_used ||
+ param->table->covering_keys.is_set(keynr);
+
+ found_records= check_quick_select(param, idx, read_index_only, *key,
+ update_tbl_stats, &mrr_flags,
+ &buf_size, &cost);
- found_records= check_quick_select(param, idx, *key, update_tbl_stats);
- if (param->is_ror_scan)
+ if ((found_records != HA_POS_ERROR) && param->is_ror_scan)
{
tree->n_ror_scans++;
tree->ror_scans_map.set_bit(idx);
}
- double cpu_cost= (double) found_records / TIME_FOR_COMPARE;
- if (found_records != HA_POS_ERROR && found_records > 2 &&
- read_index_only &&
- (param->table->file->index_flags(keynr, param->max_key_part,1) &
- HA_KEYREAD_ONLY) &&
- !(pk_is_clustered && keynr == param->table->s->primary_key))
- {
- /*
- We can resolve this by only reading through this key.
- 0.01 is added to avoid races between range and 'index' scan.
- */
- found_read_time= param->table->file->keyread_time(keynr, 1, found_records) +
- cpu_cost + 0.01;
- }
- else
- {
- /*
- cost(read_through_index) = cost(disk_io) + cost(row_in_range_checks)
- The row_in_range check is in QUICK_RANGE_SELECT::cmp_next function.
- */
- found_read_time= param->table->file->read_time(keynr,
- param->range_count,
- found_records) +
- cpu_cost + 0.01;
- }
- DBUG_PRINT("info",("key %s: found_read_time: %g (cur. read_time: %g)",
- param->table->key_info[keynr].name, found_read_time,
- read_time));
-
- if (read_time > found_read_time && found_records != HA_POS_ERROR)
+ if (found_records != HA_POS_ERROR &&
+ read_time > (found_read_time= cost.total_cost()))
{
read_time= found_read_time;
best_records= found_records;
key_to_read= key;
+ best_mrr_flags= mrr_flags;
+ best_buf_size= buf_size;
}
-
}
}
@@ -4889,11 +4938,13 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
if (key_to_read)
{
idx= key_to_read - tree->keys;
- if ((read_plan= new (param->mem_root) TRP_RANGE(*key_to_read, idx)))
+ if ((read_plan= new (param->mem_root) TRP_RANGE(*key_to_read, idx,
+ best_mrr_flags)))
{
read_plan->records= best_records;
read_plan->is_ror= tree->ror_scans_map.is_set(idx);
read_plan->read_cost= read_time;
+ read_plan->mrr_buf_size= best_buf_size;
DBUG_PRINT("info",
("Returning range plan for key %s, cost %g, records %lu",
param->table->key_info[param->real_keynr[idx]].name,
@@ -4956,7 +5007,9 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
for (; first_scan != last_scan;++first_scan)
{
if (!(quick= get_quick_select(param, (*first_scan)->idx,
- (*first_scan)->sel_arg, alloc)) ||
+ (*first_scan)->sel_arg,
+ HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
+ 0, alloc)) ||
quick_intrsect->push_quick_back(alloc, quick))
{
delete quick_intrsect;
@@ -4966,7 +5019,9 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
if (cpk_scan)
{
if (!(quick= get_quick_select(param, cpk_scan->idx,
- cpk_scan->sel_arg, alloc)))
+ cpk_scan->sel_arg,
+ HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
+ 0, alloc)))
{
delete quick_intrsect;
DBUG_RETURN(NULL);
@@ -5446,7 +5501,7 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
DBUG_RETURN(tree);
}
/* Here when simple cond */
- if (cond->const_item())
+ if (cond->const_item() && !cond->is_expensive())
{
/*
During the cond->val_int() evaluation we can come across a subselect
@@ -7371,324 +7426,124 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
}
#endif
-
-
/*
- Calculate estimate of number records that will be retrieved by a range
- scan on given index using given SEL_ARG intervals tree.
+ Calculate cost and E(#rows) for a given index and intervals tree
+
SYNOPSIS
- check_quick_select
- param Parameter from test_quick_select
- idx Number of index to use in tree->keys
- tree Transformed selection condition, tree->keys[idx]
- holds the range tree to be used for scanning.
- update_tbl_stats If true, update table->quick_keys with information
+ check_quick_select()
+ param Parameter from test_quick_select
+ idx Number of index to use in PARAM::key SEL_TREE::key
+ index_only TRUE - assume only index tuples will be accessed
+ FALSE - assume full table rows will be read
+ tree Transformed selection condition, tree->key[idx] holds
+ the intervals for the given index.
+ update_tbl_stats TRUE <=> update table->quick_* with information
about range scan we've evaluated.
+ mrr_flags INOUT MRR access flags
+ cost OUT Scan cost
NOTES
param->is_ror_scan is set to reflect if the key scan is a ROR (see
is_key_scan_ror function for more info)
param->table->quick_*, param->range_count (and maybe others) are
- updated with data of given key scan, see check_quick_keys for details.
+ updated with data of given key scan, see quick_range_seq_next for details.
RETURN
Estimate # of records to be retrieved.
HA_POS_ERROR if estimate calculation failed due to table handler problems.
-
*/
-static ha_rows
-check_quick_select(PARAM *param,uint idx,SEL_ARG *tree, bool update_tbl_stats)
-{
- ha_rows records;
- bool cpk_scan;
- uint key;
+static
+ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
+ SEL_ARG *tree, bool update_tbl_stats,
+ uint *mrr_flags, uint *bufsize, COST_VECT *cost)
+{
+ SEL_ARG_RANGE_SEQ seq;
+ RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0};
+ handler *file= param->table->file;
+ ha_rows rows;
+ uint keynr= param->real_keynr[idx];
DBUG_ENTER("check_quick_select");
+
+ /* Handle cases when we don't have a valid non-empty list of range */
+ if (!tree)
+ DBUG_RETURN(HA_POS_ERROR);
+ if (tree->type == SEL_ARG::IMPOSSIBLE)
+ DBUG_RETURN(0L);
+ if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
+ DBUG_RETURN(HA_POS_ERROR);
- param->is_ror_scan= FALSE;
- param->first_null_comp= 0;
+ seq.keyno= idx;
+ seq.real_keyno= keynr;
+ seq.param= param;
+ seq.start= tree;
- if (!tree)
- DBUG_RETURN(HA_POS_ERROR); // Can't use it
- param->max_key_part=0;
param->range_count=0;
- key= param->real_keynr[idx];
+ param->max_key_part=0;
- if (tree->type == SEL_ARG::IMPOSSIBLE)
- DBUG_RETURN(0L); // Impossible select. return
- if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
- DBUG_RETURN(HA_POS_ERROR); // Don't use tree
+ param->is_ror_scan= TRUE;
+ if (file->index_flags(keynr, 0, TRUE) & HA_KEY_SCAN_NOT_ROR)
+ param->is_ror_scan= FALSE;
+
+ *mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
+ /*
+ Pass HA_MRR_SORTED to see if MRR implementation can handle sorting.
+ */
+ *mrr_flags|= HA_MRR_NO_ASSOCIATION | HA_MRR_SORTED;
- enum ha_key_alg key_alg= param->table->key_info[key].algorithm;
- if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
- {
- /* Records are not ordered by rowid for other types of indexes. */
- cpk_scan= FALSE;
- }
- else
- {
- /*
- Clustered PK scan is a special case, check_quick_keys doesn't recognize
- CPK scans as ROR scans (while actually any CPK scan is a ROR scan).
- */
- cpk_scan= ((param->table->s->primary_key == param->real_keynr[idx]) &&
- param->table->file->primary_key_is_clustered());
- param->is_ror_scan= !cpk_scan;
- }
- param->n_ranges= 0;
+ bool pk_is_clustered= file->primary_key_is_clustered();
+ if (index_only &&
+ (file->index_flags(keynr, param->max_key_part, 1) & HA_KEYREAD_ONLY) &&
+ !(pk_is_clustered && keynr == param->table->s->primary_key))
+ *mrr_flags |= HA_MRR_INDEX_ONLY;
+
+ if (current_thd->lex->sql_command != SQLCOM_SELECT)
+ *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
- records= check_quick_keys(param, idx, tree,
- param->min_key, 0, -1,
- param->max_key, 0, -1);
- if (records != HA_POS_ERROR)
+ *bufsize= param->thd->variables.mrr_buff_size;
+ rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
+ bufsize, mrr_flags, cost);
+ if (rows != HA_POS_ERROR)
{
+ param->table->quick_rows[keynr]=rows;
if (update_tbl_stats)
{
- param->table->quick_keys.set_bit(key);
- param->table->quick_key_parts[key]=param->max_key_part+1;
- param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_keys.set_bit(keynr);
+ param->table->quick_key_parts[keynr]=param->max_key_part+1;
+ param->table->quick_n_ranges[keynr]= param->range_count;
param->table->quick_condition_rows=
- min(param->table->quick_condition_rows, records);
+ min(param->table->quick_condition_rows, rows);
}
- /*
- Need to save quick_rows in any case as it is used when calculating
- cost of ROR intersection:
- */
- param->table->quick_rows[key]=records;
- if (cpk_scan)
- param->is_ror_scan= TRUE;
}
- if (param->table->file->index_flags(key, 0, TRUE) & HA_KEY_SCAN_NOT_ROR)
- param->is_ror_scan= FALSE;
- DBUG_PRINT("exit", ("Records: %lu", (ulong) records));
- DBUG_RETURN(records);
-}
-
-
-/*
- Recursively calculate estimate of # rows that will be retrieved by
- key scan on key idx.
- SYNOPSIS
- check_quick_keys()
- param Parameter from test_quick select function.
- idx Number of key to use in PARAM::keys in list of used keys
- (param->real_keynr[idx] holds the key number in table)
- key_tree SEL_ARG tree being examined.
- min_key Buffer with partial min key value tuple
- min_key_flag
- max_key Buffer with partial max key value tuple
- max_key_flag
-
- NOTES
- The function does the recursive descent on the tree via SEL_ARG::left,
- SEL_ARG::right, and SEL_ARG::next_key_part edges. The #rows estimates
- are calculated using records_in_range calls at the leaf nodes and then
- summed.
-
- param->min_key and param->max_key are used to hold prefixes of key value
- tuples.
-
- The side effects are:
-
- param->max_key_part is updated to hold the maximum number of key parts used
- in scan minus 1.
-
- param->range_count is incremented if the function finds a range that
- wasn't counted by the caller.
-
- param->is_ror_scan is cleared if the function detects that the key scan is
- not a Rowid-Ordered Retrieval scan ( see comments for is_key_scan_ror
- function for description of which key scans are ROR scans)
-
- RETURN
- #records E(#records) for given subtree
- HA_POS_ERROR if subtree cannot be used for record retrieval
-
-*/
-
-static ha_rows
-check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
- uchar *min_key, uint min_key_flag, int min_keypart,
- uchar *max_key, uint max_key_flag, int max_keypart)
-{
- ha_rows records=0, tmp;
- uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length;
- uint tmp_min_keypart= min_keypart, tmp_max_keypart= max_keypart;
- uchar *tmp_min_key, *tmp_max_key;
- uint8 save_first_null_comp= param->first_null_comp;
-
- param->max_key_part=max(param->max_key_part,key_tree->part);
- if (key_tree->left != &null_element)
+ /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
+ enum ha_key_alg key_alg= param->table->key_info[seq.real_keyno].algorithm;
+ if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
{
- /*
- There are at least two intervals for current key part, i.e. condition
- was converted to something like
- (keyXpartY less/equals c1) OR (keyXpartY more/equals c2).
- This is not a ROR scan if the key is not Clustered Primary Key.
+ /*
+ All scans are non-ROR scans for those index types.
+ TODO: Don't have this logic here, make table engines return
+ appropriate flags instead.
*/
param->is_ror_scan= FALSE;
- records=check_quick_keys(param, idx, key_tree->left,
- min_key, min_key_flag, min_keypart,
- max_key, max_key_flag, max_keypart);
- if (records == HA_POS_ERROR) // Impossible
- return records;
}
-
- tmp_min_key= min_key;
- tmp_max_key= max_key;
- tmp_min_keypart+= key_tree->store_min(param->key[idx][key_tree->part].store_length,
- &tmp_min_key, min_key_flag);
- tmp_max_keypart+= key_tree->store_max(param->key[idx][key_tree->part].store_length,
- &tmp_max_key, max_key_flag);
- min_key_length= (uint) (tmp_min_key - param->min_key);
- max_key_length= (uint) (tmp_max_key - param->max_key);
-
- if (param->is_ror_scan)
+ else if (param->table->s->primary_key == keynr && pk_is_clustered)
{
- /*
- If the index doesn't cover entire key, mark the scan as non-ROR scan.
- Actually we're cutting off some ROR scans here.
- */
- uint16 fieldnr= param->table->key_info[param->real_keynr[idx]].
- key_part[key_tree->part].fieldnr - 1;
- if (param->table->field[fieldnr]->key_length() !=
- param->key[idx][key_tree->part].length)
- param->is_ror_scan= FALSE;
+ /* Clustered PK scan is always a ROR scan (TODO: same as above) */
+ param->is_ror_scan= TRUE;
}
-
- if (!param->first_null_comp && key_tree->is_null_interval())
- param->first_null_comp= key_tree->part+1;
-
- if (key_tree->next_key_part &&
- key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
- key_tree->next_key_part->part == key_tree->part+1)
- { // const key as prefix
- if (min_key_length == max_key_length &&
- !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
- !key_tree->min_flag && !key_tree->max_flag)
- {
- tmp=check_quick_keys(param,idx,key_tree->next_key_part, tmp_min_key,
- min_key_flag | key_tree->min_flag, tmp_min_keypart,
- tmp_max_key, max_key_flag | key_tree->max_flag,
- tmp_max_keypart);
- goto end; // Ugly, but efficient
- }
- else
- {
- /* The interval for current key part is not c1 <= keyXpartY <= c1 */
- param->is_ror_scan= FALSE;
- }
-
- tmp_min_flag=key_tree->min_flag;
- tmp_max_flag=key_tree->max_flag;
- if (!tmp_min_flag)
- tmp_min_keypart+=
- key_tree->next_key_part->store_min_key(param->key[idx], &tmp_min_key,
- &tmp_min_flag);
- if (!tmp_max_flag)
- tmp_max_keypart+=
- key_tree->next_key_part->store_max_key(param->key[idx], &tmp_max_key,
- &tmp_max_flag);
- min_key_length= (uint) (tmp_min_key - param->min_key);
- max_key_length= (uint) (tmp_max_key - param->max_key);
- }
- else
+ else if (param->range_count > 1)
{
- tmp_min_flag= min_key_flag | key_tree->min_flag;
- tmp_max_flag= max_key_flag | key_tree->max_flag;
- }
-
- if (unlikely(param->thd->killed != 0))
- return HA_POS_ERROR;
-
- keynr=param->real_keynr[idx];
- param->range_count++;
- if (!tmp_min_flag && ! tmp_max_flag &&
- (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
- (param->table->key_info[keynr].flags & HA_NOSAME) &&
- min_key_length == max_key_length &&
- !memcmp(param->min_key, param->max_key, min_key_length) &&
- !param->first_null_comp)
- {
- tmp=1; // Max one record
- param->n_ranges++;
- }
- else
- {
- if (param->is_ror_scan)
- {
- /*
- If we get here, the condition on the key was converted to form
- "(keyXpart1 = c1) AND ... AND (keyXpart{key_tree->part - 1} = cN) AND
- somecond(keyXpart{key_tree->part})"
- Check if
- somecond is "keyXpart{key_tree->part} = const" and
- uncovered "tail" of KeyX parts is either empty or is identical to
- first members of clustered primary key.
- */
- if (!(min_key_length == max_key_length &&
- !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
- !key_tree->min_flag && !key_tree->max_flag &&
- is_key_scan_ror(param, keynr, key_tree->part + 1)))
- param->is_ror_scan= FALSE;
- }
- param->n_ranges++;
-
- if (tmp_min_flag & GEOM_FLAG)
- {
- key_range min_range;
- min_range.key= param->min_key;
- min_range.length= min_key_length;
- min_range.keypart_map= make_keypart_map(tmp_min_keypart);
- /* In this case tmp_min_flag contains the handler-read-function */
- min_range.flag= (ha_rkey_function) (tmp_min_flag ^ GEOM_FLAG);
-
- tmp= param->table->file->records_in_range(keynr,
- &min_range, (key_range*) 0);
- }
- else
- {
- key_range min_range, max_range;
-
- min_range.key= param->min_key;
- min_range.length= min_key_length;
- min_range.flag= (tmp_min_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
- HA_READ_KEY_EXACT);
- min_range.keypart_map= make_keypart_map(tmp_min_keypart);
- max_range.key= param->max_key;
- max_range.length= max_key_length;
- max_range.flag= (tmp_max_flag & NEAR_MAX ?
- HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
- max_range.keypart_map= make_keypart_map(tmp_max_keypart);
- tmp=param->table->file->records_in_range(keynr,
- (min_key_length ? &min_range :
- (key_range*) 0),
- (max_key_length ? &max_range :
- (key_range*) 0));
- }
- }
- end:
- if (tmp == HA_POS_ERROR) // Impossible range
- return tmp;
- records+=tmp;
- if (key_tree->right != &null_element)
- {
- /*
- There are at least two intervals for current key part, i.e. condition
- was converted to something like
- (keyXpartY less/equals c1) OR (keyXpartY more/equals c2).
- This is not a ROR scan if the key is not Clustered Primary Key.
+ /*
+ Scaning multiple key values in the index: the records are ROR
+ for each value, but not between values. E.g, "SELECT ... x IN
+ (1,3)" returns ROR order for all records with x=1, then ROR
+ order for records with x=3
*/
param->is_ror_scan= FALSE;
- tmp=check_quick_keys(param, idx, key_tree->right,
- min_key, min_key_flag, min_keypart,
- max_key, max_key_flag, max_keypart);
- if (tmp == HA_POS_ERROR)
- return tmp;
- records+=tmp;
}
- param->first_null_comp= save_first_null_comp;
- return records;
+
+ DBUG_PRINT("exit", ("Records: %lu", (ulong) rows));
+ DBUG_RETURN(rows); //psergey-merge:todo: maintain first_null_comp.
}
@@ -7716,13 +7571,14 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
and the table has a clustered Primary Key defined as
-
PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
i.e. the first key parts of it are identical to uncovered parts ot the
key being scanned. This function assumes that the index flags do not
include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
+ Check (1) is made in quick_range_seq_next()
+
RETURN
TRUE The scan is ROR-scan
FALSE Otherwise
@@ -7735,9 +7591,19 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
KEY_PART_INFO *key_part_end= (table_key->key_part +
table_key->key_parts);
uint pk_number;
+
+ for (KEY_PART_INFO *kp= table_key->key_part; kp < key_part; kp++)
+ {
+ uint16 fieldnr= param->table->key_info[keynr].
+ key_part[kp - table_key->key_part].fieldnr - 1;
+ if (param->table->field[fieldnr]->key_length() != kp->length)
+ return FALSE;
+ }
if (key_part == key_part_end)
return TRUE;
+
+ key_part= table_key->key_part + nparts;
pk_number= param->table->s->primary_key;
if (!param->table->file->primary_key_is_clustered() || pk_number == MAX_KEY)
return FALSE;
@@ -7762,12 +7628,14 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
SYNOPSIS
get_quick_select()
param
- idx Index of used key in param->key.
- key_tree SEL_ARG tree for the used key
- parent_alloc If not NULL, use it to allocate memory for
- quick select data. Otherwise use quick->alloc.
+ idx Index of used key in param->key.
+ key_tree SEL_ARG tree for the used key
+ mrr_flags MRR parameter for quick select
+ mrr_buf_size MRR parameter for quick select
+ parent_alloc If not NULL, use it to allocate memory for
+ quick select data. Otherwise use quick->alloc.
NOTES
- The caller must call QUICK_SELECT::init for returned quick select
+ The caller must call QUICK_SELECT::init for returned quick select.
CAUTION! This function may change thd->mem_root to a MEM_ROOT which will be
deallocated when the returned quick select is deleted.
@@ -7778,25 +7646,26 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
*/
QUICK_RANGE_SELECT *
-get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree,
- MEM_ROOT *parent_alloc)
+get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree, uint mrr_flags,
+ uint mrr_buf_size, MEM_ROOT *parent_alloc)
{
QUICK_RANGE_SELECT *quick;
+ bool create_err= FALSE;
DBUG_ENTER("get_quick_select");
if (param->table->key_info[param->real_keynr[idx]].flags & HA_SPATIAL)
quick=new QUICK_RANGE_SELECT_GEOM(param->thd, param->table,
param->real_keynr[idx],
test(parent_alloc),
- parent_alloc);
+ parent_alloc, &create_err);
else
quick=new QUICK_RANGE_SELECT(param->thd, param->table,
param->real_keynr[idx],
- test(parent_alloc));
+ test(parent_alloc), NULL, &create_err);
if (quick)
{
- if (quick->error ||
+ if (create_err ||
get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
param->max_key,0))
{
@@ -7805,6 +7674,8 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree,
}
else
{
+ quick->mrr_flags= mrr_flags;
+ quick->mrr_buf_size= mrr_buf_size;
quick->key_parts=(KEY_PART*)
memdup_root(parent_alloc? parent_alloc : &quick->alloc,
(char*) param->key[idx],
@@ -7953,7 +7824,20 @@ bool QUICK_RANGE_SELECT::unique_key_range()
}
-/* Returns TRUE if any part of the key is NULL */
+
+/*
+ Return TRUE if any part of the key is NULL
+
+ SYNOPSIS
+ null_part_in_key()
+ key_part Array of key parts (index description)
+ key Key values tuple
+ length Length of key values tuple in bytes.
+
+ RETURN
+ TRUE The tuple has at least one "keypartX is NULL"
+ FALSE Otherwise
+*/
static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length)
{
@@ -8010,6 +7894,19 @@ bool QUICK_ROR_UNION_SELECT::is_keys_used(const MY_BITMAP *fields)
}
+FT_SELECT *get_ft_select(THD *thd, TABLE *table, uint key)
+{
+ bool create_err= FALSE;
+ FT_SELECT *fts= new FT_SELECT(thd, table, key, &create_err);
+ if (create_err)
+ {
+ delete fts;
+ return NULL;
+ }
+ else
+ return fts;
+}
+
/*
Create quick select from ref/ref_or_null scan.
@@ -8038,10 +7935,12 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
KEY_PART *key_part;
QUICK_RANGE *range;
uint part;
+ bool create_err= FALSE;
+ COST_VECT cost;
old_root= thd->mem_root;
/* The following call may change thd->mem_root */
- quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0);
+ quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0, 0, &create_err);
/* save mem_root set by QUICK_RANGE_SELECT constructor */
alloc= thd->mem_root;
/*
@@ -8050,7 +7949,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
*/
thd->mem_root= old_root;
- if (!quick)
+ if (!quick || create_err)
return 0; /* no ranges found */
if (quick->init())
goto err;
@@ -8104,8 +8003,25 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
goto err;
}
- return quick;
+ /* Call multi_range_read_info() to get the MRR flags and buffer size */
+ quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
+ (table->key_read ? HA_MRR_INDEX_ONLY : 0);
+ if (thd->lex->sql_command != SQLCOM_SELECT)
+ quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
+ if (!ref->null_ref_key && !key_has_nulls(key_info, range->min_key,
+ ref->key_length))
+ quick->mrr_flags |= HA_MRR_NO_NULL_ENDPOINTS;
+#endif
+ quick->mrr_buf_size= thd->variables.mrr_buff_size;
+ if (table->file->multi_range_read_info(quick->index, 1, (uint)records,
+ ~0,
+ &quick->mrr_buf_size,
+ &quick->mrr_flags, &cost))
+ goto err;
+
+ return quick;
err:
delete quick;
return 0;
@@ -8427,12 +8343,12 @@ int QUICK_ROR_UNION_SELECT::get_next()
{
if (error != HA_ERR_END_OF_FILE)
DBUG_RETURN(error);
- queue_remove(&queue, 0);
+ queue_remove_top(&queue);
}
else
{
quick->save_last_pos();
- queue_replaced(&queue);
+ queue_replace_top(&queue);
}
if (!have_prev_rowid)
@@ -8457,12 +8373,12 @@ int QUICK_ROR_UNION_SELECT::get_next()
int QUICK_RANGE_SELECT::reset()
{
- uint mrange_bufsiz;
+ uint buf_size;
uchar *mrange_buff;
+ int error;
+ HANDLER_BUFFER empty_buf;
DBUG_ENTER("QUICK_RANGE_SELECT::reset");
- next=0;
last_range= NULL;
- in_range= FALSE;
cur_range= (QUICK_RANGE**) ranges.buffer;
if (file->inited == handler::NONE)
@@ -8473,69 +8389,43 @@ int QUICK_RANGE_SELECT::reset()
DBUG_RETURN(error);
}
- /* Do not allocate the buffers twice. */
- if (multi_range_length)
+ /* Allocate buffer if we need one but haven't allocated it yet */
+ if (mrr_buf_size && !mrr_buf_desc)
{
- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
- DBUG_RETURN(0);
- }
-
- /* Allocate the ranges array. */
- DBUG_ASSERT(ranges.elements);
- multi_range_length= min(multi_range_count, ranges.elements);
- DBUG_ASSERT(multi_range_length > 0);
- while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
- my_malloc(multi_range_length *
- sizeof(KEY_MULTI_RANGE),
- MYF(MY_WME))))
- {
- /* Try to shrink the buffers until it is 0. */
- multi_range_length/= 2;
- }
- if (! multi_range)
- {
- multi_range_length= 0;
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
-
- /* Allocate the handler buffer if necessary. */
- if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
- {
- mrange_bufsiz= min(multi_range_bufsiz,
- ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
-
- while (mrange_bufsiz &&
- ! my_multi_malloc(MYF(MY_WME),
- &multi_range_buff,
- (uint) sizeof(*multi_range_buff),
- &mrange_buff, (uint) mrange_bufsiz,
- NullS))
+ buf_size= mrr_buf_size;
+ while (buf_size && !my_multi_malloc(MYF(MY_WME),
+ &mrr_buf_desc, sizeof(*mrr_buf_desc),
+ &mrange_buff, buf_size,
+ NullS))
{
/* Try to shrink the buffers until both are 0. */
- mrange_bufsiz/= 2;
+ buf_size/= 2;
}
- if (! multi_range_buff)
- {
- my_free((char*) multi_range, MYF(0));
- multi_range= NULL;
- multi_range_length= 0;
+ if (!mrr_buf_desc)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
/* Initialize the handler buffer. */
- multi_range_buff->buffer= mrange_buff;
- multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz;
- multi_range_buff->end_of_used_area= mrange_buff;
-#ifdef HAVE_valgrind
+ mrr_buf_desc->buffer= mrange_buff;
+ mrr_buf_desc->buffer_end= mrange_buff + buf_size;
+ mrr_buf_desc->end_of_used_area= mrange_buff;
+#ifdef HAVE_purify
/*
We need this until ndb will use the buffer efficiently
(Now ndb stores complete row in here, instead of only the used fields
which gives us valgrind warnings in compare_record[])
*/
- bzero((char*) mrange_buff, mrange_bufsiz);
+ bzero((char*) mrange_buff, buf_size);
#endif
}
- DBUG_RETURN(0);
+
+ if (!mrr_buf_desc)
+ empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL;
+
+ RANGE_SEQ_IF seq_funcs= {NULL, quick_range_seq_init, quick_range_seq_next, 0, 0};
+ error= file->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
+ mrr_flags, mrr_buf_desc? mrr_buf_desc:
+ &empty_buf);
+ DBUG_RETURN(error);
}
@@ -8556,13 +8446,8 @@ int QUICK_RANGE_SELECT::reset()
int QUICK_RANGE_SELECT::get_next()
{
- int result;
- KEY_MULTI_RANGE *mrange;
+ char *dummy;
DBUG_ENTER("QUICK_RANGE_SELECT::get_next");
- DBUG_ASSERT(multi_range_length && multi_range &&
- (cur_range >= (QUICK_RANGE**) ranges.buffer) &&
- (cur_range <= (QUICK_RANGE**) ranges.buffer + ranges.elements));
-
if (in_ror_merged_scan)
{
/*
@@ -8572,46 +8457,8 @@ int QUICK_RANGE_SELECT::get_next()
head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap);
}
- for (;;)
- {
- if (in_range)
- {
- /* We did already start to read this key. */
- result= file->read_multi_range_next(&mrange);
- if (result != HA_ERR_END_OF_FILE)
- goto end;
- }
-
- uint count= min(multi_range_length, ranges.elements -
- (cur_range - (QUICK_RANGE**) ranges.buffer));
- if (count == 0)
- {
- /* Ranges have already been used up before. None is left for read. */
- in_range= FALSE;
- if (in_ror_merged_scan)
- head->column_bitmaps_set_no_signal(save_read_set, save_write_set);
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
- KEY_MULTI_RANGE *mrange_slot, *mrange_end;
- for (mrange_slot= multi_range, mrange_end= mrange_slot+count;
- mrange_slot < mrange_end;
- mrange_slot++)
- {
- last_range= *(cur_range++);
- last_range->make_min_endpoint(&mrange_slot->start_key);
- last_range->make_max_endpoint(&mrange_slot->end_key);
- mrange_slot->range_flag= last_range->flag;
- }
-
- result= file->read_multi_range_first(&mrange, multi_range, count,
- sorted, multi_range_buff);
- if (result != HA_ERR_END_OF_FILE)
- goto end;
- in_range= FALSE; /* No matching rows; go to next set of ranges. */
- }
+ int result= file->multi_range_read_next(&dummy);
-end:
- in_range= ! result;
if (in_ror_merged_scan)
{
/* Restore bitmaps set on entry */
@@ -8620,6 +8467,7 @@ end:
DBUG_RETURN(result);
}
+
/*
Get the next record with a different prefix.
@@ -8658,9 +8506,7 @@ int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
int result;
if (last_range)
{
- /*
- Read the next record in the same range with prefix after cur_prefix.
- */
+ /* Read the next record in the same range with prefix after cur_prefix. */
DBUG_ASSERT(cur_prefix != NULL);
result= file->ha_index_read_map(record, cur_prefix, keypart_map,
HA_READ_AFTER_KEY);
@@ -8789,7 +8635,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
*/
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
- uint used_key_parts_arg)
+ uint used_key_parts_arg,
+ bool *create_err)
:QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
used_key_parts (used_key_parts_arg)
{
@@ -8798,9 +8645,9 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
Use default MRR implementation for reverse scans. No table engine
currently can do an MRR scan with output in reverse index order.
*/
- multi_range_length= 0;
- multi_range= NULL;
- multi_range_buff= NULL;
+ mrr_buf_desc= NULL;
+ mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
+ mrr_buf_size= 0;
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
QUICK_RANGE **end_range= pr + ranges.elements;
@@ -8909,6 +8756,7 @@ int QUICK_SELECT_DESC::get_next()
/*
Compare if found key is over max-value
Returns 0 if key <= range->max_key
+ TODO: Figure out why can't this function be as simple as cmp_prev().
*/
int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
@@ -9641,8 +9489,14 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
cur_index_tree= get_index_range_tree(cur_index, tree, param,
&cur_param_idx);
/* Check if this range tree can be used for prefix retrieval. */
+ COST_VECT dummy_cost;
+ uint mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
+ uint mrr_bufsize=0;
cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
- cur_index_tree, TRUE);
+ FALSE /*don't care*/,
+ cur_index_tree, TRUE,
+ &mrr_flags, &mrr_bufsize,
+ &dummy_cost);
}
cost_group_min_max(table, cur_index_info, cur_used_key_parts,
cur_group_key_parts, tree, cur_index_tree,
@@ -9762,7 +9616,9 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
the MIN/MAX argument field, and disallow the optimization only if this is
so.
*/
- if (cond_type == Item::SUBSELECT_ITEM)
+ if (cond_type == Item::SUBSELECT_ITEM ||
+ (cond->get_cached_item() &&
+ cond->get_cached_item()->type() == Item::SUBSELECT_ITEM))
DBUG_RETURN(FALSE);
/*
@@ -10230,6 +10086,7 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows,
/* Make a QUICK_RANGE_SELECT to be used for group prefix retrieval. */
quick->quick_prefix_select= get_quick_select(param, param_idx,
index_tree,
+ HA_MRR_USE_DEFAULT_IMPL, 0,
&quick->alloc);
/*
@@ -11320,7 +11177,8 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
if (!tmp.length())
tmp.append(STRING_WITH_LEN("(empty)"));
- DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, tmp.ptr()));
+ DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg,
+ tmp.c_ptr_safe()));
DBUG_VOID_RETURN;
}
@@ -11343,10 +11201,11 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
}
if (!tmp.length())
tmp.append(STRING_WITH_LEN("(empty)"));
- DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr()));
+ DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.c_ptr()));
DBUG_VOID_RETURN;
}
+
/*****************************************************************************
** Print a quick range for debugging
** TODO:
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 29df043cb69..fe8d3eae6c7 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -193,13 +193,16 @@ class QUICK_RANGE :public Sql_alloc {
4. Delete the select:
delete quick;
-
+
+ NOTE
+ quick select doesn't use Sql_alloc/MEM_ROOT allocation because "range
+ checked for each record" functionality may create/destroy
+ O(#records_in_some_table) quick selects during query execution.
*/
class QUICK_SELECT_I
{
public:
- bool sorted;
ha_rows records; /* estimate of # of records to be retrieved */
double read_time; /* time to perform this retrieval */
TABLE *head;
@@ -272,6 +275,12 @@ public:
virtual bool reverse_sorted() = 0;
virtual bool unique_key_range() { return false; }
+ /*
+ Request that this quick select produces sorted output. Not all quick
+ selects can do it, the caller is responsible for calling this function
+ only for those quick selects that can.
+ */
+ virtual void need_sorted_output() = 0;
enum {
QS_TYPE_RANGE = 0,
QS_TYPE_INDEX_MERGE = 1,
@@ -351,6 +360,22 @@ struct st_qsel_param;
class PARAM;
class SEL_ARG;
+
+/*
+ MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
+ context.
+*/
+typedef struct st_quick_range_seq_ctx
+{
+ QUICK_RANGE **first;
+ QUICK_RANGE **cur;
+ QUICK_RANGE **last;
+} QUICK_RANGE_SEQ_CTX;
+
+range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags);
+bool quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
+
+
/*
Quick select that does a range scan on a single key. The records are
returned in key order.
@@ -358,62 +383,47 @@ class SEL_ARG;
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
{
protected:
- bool next,dont_free,in_ror_merged_scan;
/* true if we enabled key only reads */
bool doing_key_read;
-public:
- int error;
-protected:
handler *file;
- /*
- If true, this quick select has its "own" handler object which should be
- closed no later then this quick select is deleted.
- */
- bool free_file;
- bool in_range;
- uint multi_range_count; /* copy from thd->variables.multi_range_count */
- uint multi_range_length; /* the allocated length for the array */
- uint multi_range_bufsiz; /* copy from thd->variables.read_rnd_buff_size */
- KEY_MULTI_RANGE *multi_range; /* the multi-range array (allocated and
- freed by QUICK_RANGE_SELECT) */
- HANDLER_BUFFER *multi_range_buff; /* the handler buffer (allocated and
- freed by QUICK_RANGE_SELECT) */
+
+ /* Members to deal with case when this quick select is a ROR-merged scan */
+ bool in_ror_merged_scan;
MY_BITMAP column_bitmap, *save_read_set, *save_write_set;
+ bool free_file; /* TRUE <=> this->file is "owned" by this quick select */
- friend class TRP_ROR_INTERSECT;
- friend
- QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
- struct st_table_ref *ref,
- ha_rows records);
- friend bool get_quick_keys(PARAM *param,
- QUICK_RANGE_SELECT *quick,KEY_PART *key,
- SEL_ARG *key_tree,
- uchar *min_key, uint min_key_flag,
- uchar *max_key, uint max_key_flag);
- friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx,
- SEL_ARG *key_tree,
- MEM_ROOT *alloc);
- friend class QUICK_SELECT_DESC;
- friend class QUICK_INDEX_MERGE_SELECT;
- friend class QUICK_ROR_INTERSECT_SELECT;
- friend class QUICK_GROUP_MIN_MAX_SELECT;
+ /* Range pointers to be used when not using MRR interface */
+ /* Members needed to use the MRR interface */
+ QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
+public:
+ uint mrr_flags; /* Flags to be used with MRR interface */
+protected:
+ uint mrr_buf_size; /* copy from thd->variables.mrr_buff_size */
+ HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
+ /* Info about index we're scanning */
+
DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
QUICK_RANGE **cur_range; /* current element in ranges */
-
+
QUICK_RANGE *last_range;
+
KEY_PART *key_parts;
KEY_PART_INFO *key_part_info;
+
+ bool dont_free; /* Used by QUICK_SELECT_DESC */
+
int cmp_next(QUICK_RANGE *range);
int cmp_prev(QUICK_RANGE *range);
bool row_in_ranges();
public:
MEM_ROOT alloc;
- QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0,
- MEM_ROOT *parent_alloc=NULL);
+ QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc,
+ MEM_ROOT *parent_alloc, bool *create_err);
~QUICK_RANGE_SELECT();
-
+
+ void need_sorted_output();
int init();
int reset(void);
int get_next();
@@ -433,6 +443,27 @@ public:
#endif
private:
/* Default copy ctor used by QUICK_SELECT_DESC */
+ friend class TRP_ROR_INTERSECT;
+ friend
+ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
+ struct st_table_ref *ref,
+ ha_rows records);
+ friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick,
+ KEY_PART *key, SEL_ARG *key_tree,
+ uchar *min_key, uint min_key_flag,
+ uchar *max_key, uint max_key_flag);
+ friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx,
+ SEL_ARG *key_tree,
+ uint mrr_flags,
+ uint mrr_buf_size,
+ MEM_ROOT *alloc);
+ friend class QUICK_SELECT_DESC;
+ friend class QUICK_INDEX_MERGE_SELECT;
+ friend class QUICK_ROR_INTERSECT_SELECT;
+ friend class QUICK_GROUP_MIN_MAX_SELECT;
+ friend bool quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
+ friend range_seq_t quick_range_seq_init(void *init_param,
+ uint n_ranges, uint flags);
};
@@ -440,8 +471,10 @@ class QUICK_RANGE_SELECT_GEOM: public QUICK_RANGE_SELECT
{
public:
QUICK_RANGE_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg,
- bool no_alloc, MEM_ROOT *parent_alloc)
- :QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc)
+ bool no_alloc, MEM_ROOT *parent_alloc,
+ bool *create_err)
+ :QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc,
+ create_err)
{};
virtual int get_next();
};
@@ -514,6 +547,7 @@ public:
~QUICK_INDEX_MERGE_SELECT();
int init();
+ void need_sorted_output() { DBUG_ASSERT(0); /* Can't do it */ }
int reset(void);
int get_next();
bool reverse_sorted() { return false; }
@@ -573,6 +607,7 @@ public:
~QUICK_ROR_INTERSECT_SELECT();
int init();
+ void need_sorted_output() { DBUG_ASSERT(0); /* Can't do it */ }
int reset(void);
int get_next();
bool reverse_sorted() { return false; }
@@ -635,6 +670,7 @@ public:
~QUICK_ROR_UNION_SELECT();
int init();
+ void need_sorted_output() { DBUG_ASSERT(0); /* Can't do it */ }
int reset(void);
int get_next();
bool reverse_sorted() { return false; }
@@ -756,6 +792,7 @@ public:
void adjust_prefix_ranges();
bool alloc_buffers();
int init();
+ void need_sorted_output() { /* always do it */ }
int reset();
int get_next();
bool reverse_sorted() { return false; }
@@ -771,7 +808,8 @@ public:
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
{
public:
- QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts);
+ QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts,
+ bool *create_err);
int get_next();
bool reverse_sorted() { return 1; }
int get_type() { return QS_TYPE_RANGE_DESC; }
@@ -788,6 +826,13 @@ class SQL_SELECT :public Sql_alloc {
public:
QUICK_SELECT_I *quick; // If quick-select used
COND *cond; // where condition
+
+ /*
+ When using Index Condition Pushdown: condition that we've had before
+ extracting and pushing index condition.
+ In other cases, NULL.
+ */
+ Item *pre_idx_push_select_cond;
TABLE *head;
IO_CACHE file; // Positions to used records
ha_rows records; // Records in use if read from file
@@ -804,7 +849,7 @@ class SQL_SELECT :public Sql_alloc {
{
key_map tmp;
tmp.set_all();
- return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0;
+ return test_quick_select(thd, tmp, 0, limit, force_quick_range, FALSE) < 0;
}
/*
RETURN
@@ -820,21 +865,25 @@ class SQL_SELECT :public Sql_alloc {
return rc;
}
int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
- ha_rows limit, bool force_quick_range);
+ ha_rows limit, bool force_quick_range,
+ bool ordered_output);
};
-class FT_SELECT: public QUICK_RANGE_SELECT {
+class FT_SELECT: public QUICK_RANGE_SELECT
+{
public:
- FT_SELECT(THD *thd, TABLE *table, uint key) :
- QUICK_RANGE_SELECT (thd, table, key, 1) { VOID(init()); }
+ FT_SELECT(THD *thd, TABLE *table, uint key, bool *create_err) :
+ QUICK_RANGE_SELECT (thd, table, key, 1, NULL, create_err)
+ { (void) init(); }
~FT_SELECT() { file->ft_end(); }
- int init() { return error=file->ft_init(); }
+ int init() { return file->ft_init(); }
int reset() { return 0; }
- int get_next() { return error= file->ha_ft_read(record); }
+ int get_next() { return file->ha_ft_read(record); }
int get_type() { return QS_TYPE_FULLTEXT; }
};
+FT_SELECT *get_ft_select(THD *thd, TABLE *table, uint key);
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
struct st_table_ref *ref,
ha_rows records);
diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc
new file mode 100644
index 00000000000..e5da9577f7f
--- /dev/null
+++ b/sql/opt_range_mrr.cc
@@ -0,0 +1,332 @@
+
+/****************************************************************************
+ MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
+ ****************************************************************************/
+
+/* MRR range sequence, SEL_ARG* implementation: stack entry */
+typedef struct st_range_seq_entry
+{
+ /*
+ Pointers in min and max keys. They point to right-after-end of key
+ images. The 0-th entry has these pointing to key tuple start.
+ */
+ uchar *min_key, *max_key;
+
+ /*
+ Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
+ min_key_flag may have NULL_RANGE set.
+ */
+ uint min_key_flag, max_key_flag;
+
+ /* Number of key parts */
+ uint min_key_parts, max_key_parts;
+ SEL_ARG *key_tree;
+} RANGE_SEQ_ENTRY;
+
+
+/*
+ MRR range sequence, SEL_ARG* implementation: SEL_ARG graph traversal context
+*/
+typedef struct st_sel_arg_range_seq
+{
+ uint keyno; /* index of used tree in SEL_TREE structure */
+ uint real_keyno; /* Number of the index in tables */
+ PARAM *param;
+ SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
+
+ RANGE_SEQ_ENTRY stack[MAX_REF_PARTS];
+ int i; /* Index of last used element in the above array */
+
+ bool at_start; /* TRUE <=> The traversal has just started */
+} SEL_ARG_RANGE_SEQ;
+
+
+/*
+ Range sequence interface, SEL_ARG* implementation: Initialize the traversal
+
+ SYNOPSIS
+ init()
+ init_params SEL_ARG tree traversal context
+ n_ranges [ignored] The number of ranges obtained
+ flags [ignored] HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
+
+ RETURN
+ Value of init_param
+*/
+
+range_seq_t sel_arg_range_seq_init(void *init_param, uint n_ranges, uint flags)
+{
+ SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
+ seq->at_start= TRUE;
+ seq->stack[0].key_tree= NULL;
+ seq->stack[0].min_key= seq->param->min_key;
+ seq->stack[0].min_key_flag= 0;
+ seq->stack[0].min_key_parts= 0;
+
+ seq->stack[0].max_key= seq->param->max_key;
+ seq->stack[0].max_key_flag= 0;
+ seq->stack[0].max_key_parts= 0;
+ seq->i= 0;
+ return init_param;
+}
+
+
+static void step_down_to(SEL_ARG_RANGE_SEQ *arg, SEL_ARG *key_tree)
+{
+ RANGE_SEQ_ENTRY *cur= &arg->stack[arg->i+1];
+ RANGE_SEQ_ENTRY *prev= &arg->stack[arg->i];
+
+ cur->key_tree= key_tree;
+ cur->min_key= prev->min_key;
+ cur->max_key= prev->max_key;
+ cur->min_key_parts= prev->min_key_parts;
+ cur->max_key_parts= prev->max_key_parts;
+
+ uint16 stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
+ cur->min_key_parts += key_tree->store_min(stor_length, &cur->min_key,
+ prev->min_key_flag);
+ cur->max_key_parts += key_tree->store_max(stor_length, &cur->max_key,
+ prev->max_key_flag);
+
+ cur->min_key_flag= prev->min_key_flag | key_tree->min_flag;
+ cur->max_key_flag= prev->max_key_flag | key_tree->max_flag;
+
+ if (key_tree->is_null_interval())
+ cur->min_key_flag |= NULL_RANGE;
+ (arg->i)++;
+}
+
+
+/*
+ Range sequence interface, SEL_ARG* implementation: get the next interval
+
+ SYNOPSIS
+ sel_arg_range_seq_next()
+ rseq Value returned from sel_arg_range_seq_init
+ range OUT Store information about the range here
+
+ DESCRIPTION
+ This is "get_next" function for Range sequence interface implementation
+ for SEL_ARG* tree.
+
+ IMPLEMENTATION
+ The traversal also updates those param members:
+ - is_ror_scan
+ - range_count
+ - max_key_part
+
+ RETURN
+ FALSE Ok
+ TRUE No more ranges in the sequence
+*/
+
+bool sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
+{
+ SEL_ARG *key_tree;
+ SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
+ if (seq->at_start)
+ {
+ key_tree= seq->start;
+ seq->at_start= FALSE;
+ goto walk_up_n_right;
+ }
+
+ key_tree= seq->stack[seq->i].key_tree;
+ /* Ok, we're at some "full tuple" position in the tree */
+
+ /* Step down if we can */
+ if (key_tree->next && key_tree->next != &null_element)
+ {
+ //step down; (update the tuple, we'll step right and stay there)
+ seq->i--;
+ step_down_to(seq, key_tree->next);
+ key_tree= key_tree->next;
+ seq->param->is_ror_scan= FALSE;
+ goto walk_right_n_up;
+ }
+
+ /* Ok, can't step down, walk left until we can step down */
+ while (1)
+ {
+ if (seq->i == 1) // can't step left
+ return 1;
+ /* Step left */
+ seq->i--;
+ key_tree= seq->stack[seq->i].key_tree;
+
+ /* Step down if we can */
+ if (key_tree->next && key_tree->next != &null_element)
+ {
+ // Step down; update the tuple
+ seq->i--;
+ step_down_to(seq, key_tree->next);
+ key_tree= key_tree->next;
+ break;
+ }
+ }
+
+ /*
+ Ok, we've stepped down from the path to previous tuple.
+ Walk right-up while we can
+ */
+walk_right_n_up:
+ while (key_tree->next_key_part && key_tree->next_key_part != &null_element &&
+ key_tree->next_key_part->part == key_tree->part + 1 &&
+ key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
+ {
+ {
+ RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
+ uint min_key_length= cur->min_key - seq->param->min_key;
+ uint max_key_length= cur->max_key - seq->param->max_key;
+ uint len= cur->min_key - cur[-1].min_key;
+ if (!(min_key_length == max_key_length &&
+ !memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
+ !key_tree->min_flag && !key_tree->max_flag))
+ {
+ seq->param->is_ror_scan= FALSE;
+ if (!key_tree->min_flag)
+ cur->min_key_parts +=
+ key_tree->next_key_part->store_min_key(seq->param->key[seq->keyno],
+ &cur->min_key,
+ &cur->min_key_flag);
+ if (!key_tree->max_flag)
+ cur->max_key_parts +=
+ key_tree->next_key_part->store_max_key(seq->param->key[seq->keyno],
+ &cur->max_key,
+ &cur->max_key_flag);
+ break;
+ }
+ }
+
+ /*
+ Ok, current atomic interval is in form "t.field=const" and there is
+ next_key_part interval. Step right, and walk up from there.
+ */
+ key_tree= key_tree->next_key_part;
+
+walk_up_n_right:
+ while (key_tree->prev && key_tree->prev != &null_element)
+ {
+ /* Step up */
+ key_tree= key_tree->prev;
+ }
+ step_down_to(seq, key_tree);
+ }
+
+ /* Ok got a tuple */
+ RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
+ uint min_key_length= cur->min_key - seq->param->min_key;
+
+ range->ptr= (char*)(int)(key_tree->part);
+ if (cur->min_key_flag & GEOM_FLAG)
+ {
+ range->range_flag= cur->min_key_flag;
+
+ /* Here minimum contains also function code bits, and maximum is +inf */
+ range->start_key.key= seq->param->min_key;
+ range->start_key.length= min_key_length;
+ range->start_key.flag= (ha_rkey_function) (cur->min_key_flag ^ GEOM_FLAG);
+ }
+ else
+ {
+ range->range_flag= cur->min_key_flag | cur->max_key_flag;
+
+ range->start_key.key= seq->param->min_key;
+ range->start_key.length= cur->min_key - seq->param->min_key;
+ range->start_key.keypart_map= make_prev_keypart_map(cur->min_key_parts);
+ range->start_key.flag= (cur->min_key_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
+ HA_READ_KEY_EXACT);
+
+ range->end_key.key= seq->param->max_key;
+ range->end_key.length= cur->max_key - seq->param->max_key;
+ range->end_key.flag= (cur->max_key_flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
+ HA_READ_AFTER_KEY);
+ range->end_key.keypart_map= make_prev_keypart_map(cur->max_key_parts);
+
+ if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
+ (uint)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
+ (seq->param->table->key_info[seq->real_keyno].flags & HA_NOSAME) &&
+ range->start_key.length == range->end_key.length &&
+ !memcmp(seq->param->min_key,seq->param->max_key,range->start_key.length))
+ range->range_flag= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
+
+ if (seq->param->is_ror_scan)
+ {
+ /*
+ If we get here, the condition on the key was converted to form
+ "(keyXpart1 = c1) AND ... AND (keyXpart{key_tree->part - 1} = cN) AND
+ somecond(keyXpart{key_tree->part})"
+ Check if
+ somecond is "keyXpart{key_tree->part} = const" and
+ uncovered "tail" of KeyX parts is either empty or is identical to
+ first members of clustered primary key.
+ */
+ if (!(!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
+ (range->start_key.length == range->end_key.length) &&
+ !memcmp(range->start_key.key, range->end_key.key, range->start_key.length) &&
+ is_key_scan_ror(seq->param, seq->real_keyno, key_tree->part + 1)))
+ seq->param->is_ror_scan= FALSE;
+ }
+ }
+ seq->param->range_count++;
+ seq->param->max_key_part=max(seq->param->max_key_part,key_tree->part);
+ return 0;
+}
+
+/****************************************************************************
+ MRR Range Sequence Interface implementation that walks array<QUICK_RANGE>
+ ****************************************************************************/
+
+/*
+ Range sequence interface implementation for array<QUICK_RANGE>: initialize
+
+ SYNOPSIS
+ quick_range_seq_init()
+ init_param Caller-opaque paramenter: QUICK_RANGE_SELECT* pointer
+ n_ranges Number of ranges in the sequence (ignored)
+ flags MRR flags (currently not used)
+
+ RETURN
+ Opaque value to be passed to quick_range_seq_next
+*/
+
+range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags)
+{
+ QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
+ quick->qr_traversal_ctx.first= (QUICK_RANGE**)quick->ranges.buffer;
+ quick->qr_traversal_ctx.cur= (QUICK_RANGE**)quick->ranges.buffer;
+ quick->qr_traversal_ctx.last= quick->qr_traversal_ctx.cur +
+ quick->ranges.elements;
+ return &quick->qr_traversal_ctx;
+}
+
+
+/*
+ Range sequence interface implementation for array<QUICK_RANGE>: get next
+
+ SYNOPSIS
+ quick_range_seq_next()
+ rseq Value returned from quick_range_seq_init
+ range OUT Store information about the range here
+
+ RETURN
+ 0 Ok
+ 1 No more ranges in the sequence
+*/
+
+bool quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
+{
+ QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
+
+ if (ctx->cur == ctx->last)
+ return 1; /* no more ranges */
+
+ QUICK_RANGE *cur= *(ctx->cur);
+ cur->make_min_endpoint(&range->start_key);
+ cur->make_max_endpoint(&range->end_key);
+ range->range_flag= cur->flag;
+ ctx->cur++;
+ return 0;
+}
+
+
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
new file mode 100644
index 00000000000..5428467b850
--- /dev/null
+++ b/sql/opt_subselect.cc
@@ -0,0 +1,3502 @@
+/**
+ @file
+
+ @brief
+ Subquery optimization code here.
+
+*/
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+#include "opt_subselect.h"
+
+#include <my_bit.h>
+
+// Our own:
+static
+bool subquery_types_allow_materialization(Item_in_subselect *in_subs);
+static bool replace_where_subcondition(JOIN *join, Item **expr,
+ Item *old_cond, Item *new_cond,
+ bool do_fix_fields);
+static int subq_sj_candidate_cmp(Item_in_subselect* const *el1,
+ Item_in_subselect* const *el2);
+static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred);
+static TABLE_LIST *alloc_join_nest(THD *thd);
+static
+void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
+static uint get_tmp_table_rec_length(List<Item> &items);
+bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables);
+static SJ_MATERIALIZATION_INFO *
+at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
+ uint idx, bool *loose_scan);
+void best_access_path(JOIN *join, JOIN_TAB *s,
+ table_map remaining_tables, uint idx,
+ bool disable_jbuf, double record_count,
+ POSITION *pos, POSITION *loose_scan_pos);
+
+static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm,
+ Item_in_subselect *subq_pred);
+static void remove_sj_conds(Item **tree);
+static bool is_cond_sj_in_equality(Item *item);
+static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
+static Item *remove_additional_cond(Item* conds);
+static void remove_subq_pushed_predicates(JOIN *join, Item **where);
+
+
+/*
+ Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
+
+ DESCRIPTION
+ Check if we need to do
+ - subquery->semi-join rewrite
+ - if the subquery can be handled with materialization
+ - 'substitution' rewrite for table-less subqueries like "(select 1)"
+
+ and mark appropriately
+
+ RETURN
+ 0 - OK
+ -1 - Some sort of query error
+*/
+
+int check_and_do_in_subquery_rewrites(JOIN *join)
+{
+ THD *thd=join->thd;
+ st_select_lex *select_lex= join->select_lex;
+ DBUG_ENTER("check_and_do_in_subquery_rewrites");
+ /*
+ If
+ 1) this join is inside a subquery (of any type except FROM-clause
+ subquery) and
+ 2) we aren't just normalizing a VIEW
+
+ Then perform early unconditional subquery transformations:
+ - Convert subquery predicate into semi-join, or
+ - Mark the subquery for execution using materialization, or
+ - Perform IN->EXISTS transformation, or
+ - Perform more/less ALL/ANY -> MIN/MAX rewrite
+ - Substitute trivial scalar-context subquery with its value
+
+ TODO: for PS, make the whole block execute only on the first execution
+ */
+ Item_subselect *subselect;
+ if (!thd->lex->view_prepare_mode && // (1)
+ (subselect= select_lex->master_unit()->item)) // (2)
+ {
+ Item_in_subselect *in_subs= NULL;
+ if (subselect->substype() == Item_subselect::IN_SUBS)
+ in_subs= (Item_in_subselect*)subselect;
+
+ /* Resolve expressions and perform semantic analysis for IN query */
+ if (in_subs != NULL)
+ /*
+ TODO: Add the condition below to this if statement when we have proper
+ support for is_correlated handling for materialized semijoins.
+ If we were to add this condition now, the fix_fields() call in
+ convert_subq_to_sj() would force the flag is_correlated to be set
+ erroneously for prepared queries.
+
+ thd->stmt_arena->state != Query_arena::PREPARED)
+ */
+ {
+ /*
+ Check if the left and right expressions have the same # of
+ columns, i.e. we don't have a case like
+ (oe1, oe2) IN (SELECT ie1, ie2, ie3 ...)
+
+ TODO why do we have this duplicated in IN->EXISTS transformers?
+ psergey-todo: fix these: grep for duplicated_subselect_card_check
+ */
+ if (select_lex->item_list.elements != in_subs->left_expr->cols())
+ {
+ my_error(ER_OPERAND_COLUMNS, MYF(0), in_subs->left_expr->cols());
+ DBUG_RETURN(-1);
+ }
+
+ SELECT_LEX *current= thd->lex->current_select;
+ thd->lex->current_select= current->return_after_parsing();
+ char const *save_where= thd->where;
+ thd->where= "IN/ALL/ANY subquery";
+
+ bool failure= !in_subs->left_expr->fixed &&
+ in_subs->left_expr->fix_fields(thd, &in_subs->left_expr);
+ thd->lex->current_select= current;
+ thd->where= save_where;
+ if (failure)
+ DBUG_RETURN(-1); /* purecov: deadcode */
+ }
+ DBUG_PRINT("info", ("Checking if subq can be converted to semi-join"));
+ /*
+ Check if we're in subquery that is a candidate for flattening into a
+ semi-join (which is done in flatten_subqueries()). The
+ requirements are:
+ 1. Subquery predicate is an IN/=ANY subq predicate
+ 2. Subquery is a single SELECT (not a UNION)
+ 3. Subquery does not have GROUP BY or ORDER BY
+ 4. Subquery does not use aggregate functions or HAVING
+ 5. Subquery predicate is at the AND-top-level of ON/WHERE clause
+ 6. We are not in a subquery of a single table UPDATE/DELETE that
+ doesn't have a JOIN (TODO: We should handle this at some
+ point by switching to multi-table UPDATE/DELETE)
+ 7. We're not in a table-less subquery like "SELECT 1"
+ 8. No execution method was already chosen (by a prepared statement)
+ 9. Parent select is not a table-less select
+ 10. Neither parent nor child select have STRAIGHT_JOIN option.
+ */
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN) &&
+ in_subs && // 1
+ !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
+ select_lex->outer_select()->join && // 6
+ select_lex->master_unit()->first_select()->leaf_tables && // 7
+ in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED && // 8
+ select_lex->outer_select()->leaf_tables && // 9
+ !((join->select_options | // 10
+ select_lex->outer_select()->join->select_options) // 10
+ & SELECT_STRAIGHT_JOIN)) // 10
+ {
+ DBUG_PRINT("info", ("Subquery is semi-join conversion candidate"));
+
+ (void)subquery_types_allow_materialization(in_subs);
+
+ in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
+
+ /* Register the subquery for further processing in flatten_subqueries() */
+ select_lex->
+ outer_select()->join->sj_subselects.append(thd->mem_root, in_subs);
+ in_subs->expr_join_nest= thd->thd_marker.emb_on_expr_nest;
+ }
+ else
+ {
+ DBUG_PRINT("info", ("Subquery can't be converted to semi-join"));
+ /*
+ Check if the subquery predicate can be executed via materialization.
+ The required conditions are:
+ 1. Subquery predicate is an IN/=ANY subq predicate
+ 2. Subquery is a single SELECT (not a UNION)
+ 3. Subquery is not a table-less query. In this case there is no
+ point in materializing.
+ 3A 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.
+ 4. 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.
+ 5. Subquery is non-correlated
+ TODO:
+ This is an overly restrictive condition. 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"))
+ 6. No execution method was already chosen (by a prepared statement).
+
+ (*) The subquery must be part of a SELECT statement. The current
+ condition also excludes multi-table update statements.
+
+ Determine whether we will perform subquery materialization before
+ calling the IN=>EXISTS transformation, so that we know whether to
+ perform the whole transformation or only that part of it which wraps
+ Item_in_subselect in an Item_in_optimizer.
+ */
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) &&
+ in_subs && // 1
+ !select_lex->is_part_of_union() && // 2
+ select_lex->master_unit()->first_select()->leaf_tables && // 3
+ thd->lex->sql_command == SQLCOM_SELECT && // *
+ select_lex->outer_select()->leaf_tables && // 3A
+ subquery_types_allow_materialization(in_subs) &&
+ // psergey-todo: duplicated_subselect_card_check: where it's done?
+ (in_subs->is_top_level_item() ||
+ optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) ||
+ optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) &&//4
+ !in_subs->is_correlated && // 5
+ in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED) // 6
+ {
+ in_subs->exec_method= Item_in_subselect::MATERIALIZATION;
+ }
+
+ Item_subselect::trans_res trans_res;
+ if ((trans_res= subselect->select_transformer(join)) !=
+ Item_subselect::RES_OK)
+ {
+ DBUG_RETURN((trans_res == Item_subselect::RES_ERROR));
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**
+ @brief Check if subquery's compared types allow materialization.
+
+ @param in_subs Subquery predicate, updated as follows:
+ types_allow_materialization TRUE if subquery materialization is allowed.
+ sjm_scan_allowed If types_allow_materialization is TRUE,
+ indicates whether it is possible to use subquery
+ materialization and scan the materialized table.
+
+ @retval TRUE If subquery types allow materialization.
+ @retval FALSE Otherwise.
+
+ @details
+ This is a temporary fix for BUG#36752.
+
+ There are two subquery materialization strategies:
+
+ 1. Materialize and do index lookups in the materialized table. See
+ BUG#36752 for description of restrictions we need to put on the
+ compared expressions.
+
+ 2. Materialize and then do a full scan of the materialized table. At the
+ moment, this strategy's applicability criteria are even stricter than
+ in #1.
+
+ This is so because of the following: consider an uncorrelated subquery
+
+ ...WHERE (ot1.col1, ot2.col2 ...) IN (SELECT ie1,ie2,... FROM it1 ...)
+
+ and a join order that could be used to do sjm-materialization:
+
+ SJM-Scan(it1, it1), ot1, ot2
+
+ IN-equalities will be parts of conditions attached to the outer tables:
+
+ ot1: ot1.col1 = ie1 AND ... (C1)
+ ot2: ot1.col2 = ie2 AND ... (C2)
+
+ besides those there may be additional references to ie1 and ie2
+ generated by equality propagation. The problem with evaluating C1 and
+ C2 is that ie{1,2} refer to subquery tables' columns, while we only have
+ current value of materialization temptable. Our solution is to
+ * require that all ie{N} are table column references. This allows
+ to copy the values of materialization temptable columns to the
+ original table's columns (see setup_sj_materialization for more
+ details)
+ * require that compared columns have exactly the same type. This is
+ a temporary measure to avoid BUG#36752-type problems.
+*/
+
+static
+bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
+{
+ DBUG_ENTER("subquery_types_allow_materialization");
+
+ DBUG_ASSERT(in_subs->left_expr->fixed);
+
+ List_iterator<Item> it(in_subs->unit->first_select()->item_list);
+ uint elements= in_subs->unit->first_select()->item_list.elements;
+
+ in_subs->types_allow_materialization= FALSE; // Assign default values
+ in_subs->sjm_scan_allowed= FALSE;
+
+ bool all_are_fields= TRUE;
+ for (uint i= 0; i < elements; i++)
+ {
+ Item *outer= in_subs->left_expr->element_index(i);
+ Item *inner= it++;
+ all_are_fields &= (outer->real_item()->type() == Item::FIELD_ITEM &&
+ inner->real_item()->type() == Item::FIELD_ITEM);
+ if (outer->result_type() != inner->result_type())
+ DBUG_RETURN(FALSE);
+ switch (outer->result_type()) {
+ case STRING_RESULT:
+ if (outer->is_datetime() != inner->is_datetime())
+ DBUG_RETURN(FALSE);
+
+ if (!(outer->collation.collation == inner->collation.collation
+ /*&& outer->max_length <= inner->max_length */))
+ DBUG_RETURN(FALSE);
+ /*case INT_RESULT:
+ if (!(outer->unsigned_flag ^ inner->unsigned_flag))
+ DBUG_RETURN(FALSE); */
+ default:
+ ;/* suitable for materialization */
+ }
+
+ // Materialization does not work with BLOB columns
+ if (inner->field_type() == MYSQL_TYPE_BLOB ||
+ inner->field_type() == MYSQL_TYPE_GEOMETRY)
+ DBUG_RETURN(FALSE);
+ }
+
+ in_subs->types_allow_materialization= TRUE;
+ in_subs->sjm_scan_allowed= all_are_fields;
+ DBUG_PRINT("info",("subquery_types_allow_materialization: ok, allowed"));
+ DBUG_RETURN(TRUE);
+}
+
+
+/*
+ Convert semi-join subquery predicates into semi-join join nests
+
+ SYNOPSIS
+ convert_join_subqueries_to_semijoins()
+
+ DESCRIPTION
+
+ Convert candidate subquery predicates into semi-join join nests. This
+ transformation is performed once in query lifetime and is irreversible.
+
+ Conversion of one subquery predicate
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ We start with a join that has a semi-join subquery:
+
+ SELECT ...
+ FROM ot, ...
+ WHERE oe IN (SELECT ie FROM it1 ... itN WHERE subq_where) AND outer_where
+
+ and convert it into a semi-join nest:
+
+ SELECT ...
+ FROM ot SEMI JOIN (it1 ... itN), ...
+ WHERE outer_where AND subq_where AND oe=ie
+
+ that is, in order to do the conversion, we need to
+
+ * Create the "SEMI JOIN (it1 .. itN)" part and add it into the parent
+ query's FROM structure.
+ * Add "AND subq_where AND oe=ie" into parent query's WHERE (or ON if
+ the subquery predicate was in an ON expression)
+ * Remove the subquery predicate from the parent query's WHERE
+
+ Considerations when converting many predicates
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ A join may have at most MAX_TABLES tables. This may prevent us from
+ flattening all subqueries when the total number of tables in parent and
+ child selects exceeds MAX_TABLES.
+ We deal with this problem by flattening children's subqueries first and
+ then using a heuristic rule to determine each subquery predicate's
+ "priority".
+
+ RETURN
+ FALSE OK
+ TRUE Error
+*/
+
+bool convert_join_subqueries_to_semijoins(JOIN *join)
+{
+ Query_arena *arena, backup;
+ Item_in_subselect **in_subq;
+ Item_in_subselect **in_subq_end;
+ THD *thd= join->thd;
+ DBUG_ENTER("convert_join_subqueries_to_semijoins");
+
+ if (join->sj_subselects.elements() == 0)
+ DBUG_RETURN(FALSE);
+
+ /* First, convert child join's subqueries. We proceed bottom-up here */
+ for (in_subq= join->sj_subselects.front(),
+ in_subq_end= join->sj_subselects.back();
+ in_subq != in_subq_end;
+ in_subq++)
+ {
+ st_select_lex *child_select= (*in_subq)->get_select_lex();
+ JOIN *child_join= child_select->join;
+ child_join->outer_tables = child_join->tables;
+
+ /*
+ child_select->where contains only the WHERE predicate of the
+ subquery itself here. We may be selecting from a VIEW, which has its
+ own predicate. The combined predicates are available in child_join->conds,
+ which was built by setup_conds() doing prepare_where() for all views.
+ */
+ child_select->where= child_join->conds;
+
+ if (convert_join_subqueries_to_semijoins(child_join))
+ DBUG_RETURN(TRUE);
+ (*in_subq)->sj_convert_priority=
+ (*in_subq)->is_correlated * MAX_TABLES + child_join->outer_tables;
+ }
+
+ // Temporary measure: disable semi-joins when they are together with outer
+ // joins.
+ for (TABLE_LIST *tbl= join->select_lex->leaf_tables; tbl; tbl=tbl->next_leaf)
+ {
+ TABLE_LIST *embedding= tbl->embedding;
+ if (tbl->on_expr || (tbl->embedding && !(embedding->sj_on_expr &&
+ !embedding->embedding)))
+ {
+ in_subq= join->sj_subselects.front();
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ goto skip_conversion;
+ }
+ }
+
+ //dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables);
+ /*
+ 2. Pick which subqueries to convert:
+ sort the subquery array
+ - prefer correlated subqueries over uncorrelated;
+ - prefer subqueries that have greater number of outer tables;
+ */
+ join->sj_subselects.sort(subq_sj_candidate_cmp);
+ // #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
+ /* Replace all subqueries to be flattened with Item_int(1) */
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ for (in_subq= join->sj_subselects.front();
+ in_subq != in_subq_end &&
+ join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
+ in_subq++)
+ {
+ Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
+ &join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
+ if (replace_where_subcondition(join, tree, *in_subq, new Item_int(1),
+ FALSE))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ }
+
+ for (in_subq= join->sj_subselects.front();
+ in_subq != in_subq_end &&
+ join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
+ in_subq++)
+ {
+ if (convert_subq_to_sj(join, *in_subq))
+ DBUG_RETURN(TRUE);
+ }
+skip_conversion:
+ /*
+ 3. Finalize (perform IN->EXISTS rewrite) the subqueries that we didn't
+ convert:
+ */
+ for (; in_subq!= in_subq_end; in_subq++)
+ {
+ JOIN *child_join= (*in_subq)->unit->first_select()->join;
+ Item_subselect::trans_res res;
+ (*in_subq)->changed= 0;
+ (*in_subq)->fixed= 0;
+
+ SELECT_LEX *save_select_lex= thd->lex->current_select;
+ thd->lex->current_select= (*in_subq)->unit->first_select();
+
+ res= (*in_subq)->select_transformer(child_join);
+
+ thd->lex->current_select= save_select_lex;
+
+ if (res == Item_subselect::RES_ERROR)
+ DBUG_RETURN(TRUE);
+
+ (*in_subq)->changed= 1;
+ (*in_subq)->fixed= 1;
+
+ Item *substitute= (*in_subq)->substitution;
+ bool do_fix_fields= !(*in_subq)->substitution->fixed;
+ Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
+ &join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
+ if (replace_where_subcondition(join, tree, *in_subq, substitute,
+ do_fix_fields))
+ DBUG_RETURN(TRUE);
+ (*in_subq)->substitution= NULL;
+
+ if (!thd->stmt_arena->is_conventional())
+ {
+ tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
+ &join->select_lex->prep_where :
+ &((*in_subq)->emb_on_expr_nest->prep_on_expr);
+
+ if (replace_where_subcondition(join, tree, *in_subq, substitute,
+ FALSE))
+ DBUG_RETURN(TRUE);
+ }
+ }
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ join->sj_subselects.clear();
+ DBUG_RETURN(FALSE);
+}
+
+/**
+ @brief Replaces an expression destructively inside the expression tree of
+ the WHERE clase.
+
+ @note Because of current requirements for semijoin flattening, we do not
+ need to recurse here, hence this function will only examine the top-level
+ AND conditions. (see JOIN::prepare, comment starting with "Check if the
+ subquery predicate can be executed via materialization".
+
+ @param join The top-level query.
+ @param old_cond The expression to be replaced.
+ @param new_cond The expression to be substituted.
+ @param do_fix_fields If true, Item::fix_fields(THD*, Item**) is called for
+ the new expression.
+ @return <code>true</code> if there was an error, <code>false</code> if
+ successful.
+*/
+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;
+ if (do_fix_fields)
+ new_cond->fix_fields(join->thd, expr);
+ return FALSE;
+ }
+
+ if ((*expr)->type() == Item::COND_ITEM)
+ {
+ List_iterator<Item> li(*((Item_cond*)(*expr))->argument_list());
+ Item *item;
+ while ((item= li++))
+ {
+ if (item == old_cond)
+ {
+ li.replace(new_cond);
+ if (do_fix_fields)
+ new_cond->fix_fields(join->thd, li.ref());
+ return FALSE;
+ }
+ }
+ }
+ // If we came here it means there were an error during prerequisites check.
+ DBUG_ASSERT(0);
+ return TRUE;
+}
+
+static int subq_sj_candidate_cmp(Item_in_subselect* const *el1,
+ Item_in_subselect* const *el2)
+{
+ return ((*el1)->sj_convert_priority < (*el2)->sj_convert_priority) ? 1 :
+ ( ((*el1)->sj_convert_priority == (*el2)->sj_convert_priority)? 0 : -1);
+}
+
+
+/*
+ Convert a subquery predicate into a TABLE_LIST semi-join nest
+
+ SYNOPSIS
+ convert_subq_to_sj()
+ parent_join Parent join, the one that has subq_pred in its WHERE/ON
+ clause
+ subq_pred Subquery predicate to be converted
+
+ DESCRIPTION
+ Convert a subquery predicate into a TABLE_LIST semi-join nest. All the
+ prerequisites are already checked, so the conversion is always successfull.
+
+ Prepared Statements: the transformation is permanent:
+ - Changes in TABLE_LIST structures are naturally permanent
+ - Item tree changes are performed on statement MEM_ROOT:
+ = we activate statement MEM_ROOT
+ = this function is called before the first fix_prepare_information
+ call.
+
+ This is intended because the criteria for subquery-to-sj conversion remain
+ constant for the lifetime of the Prepared Statement.
+
+ RETURN
+ FALSE OK
+ TRUE Out of memory error
+*/
+
+static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
+{
+ SELECT_LEX *parent_lex= parent_join->select_lex;
+ TABLE_LIST *emb_tbl_nest= NULL;
+ List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
+ THD *thd= parent_join->thd;
+ DBUG_ENTER("convert_subq_to_sj");
+
+ /*
+ 1. Find out where to put the predicate into.
+ Note: for "t1 LEFT JOIN t2" this will be t2, a leaf.
+ */
+ if ((void*)subq_pred->expr_join_nest != (void*)1)
+ {
+ if (subq_pred->expr_join_nest->nested_join)
+ {
+ /*
+ We're dealing with
+
+ ... [LEFT] JOIN ( ... ) ON (subquery AND whatever) ...
+
+ The sj-nest will be inserted into the brackets nest.
+ */
+ emb_tbl_nest= subq_pred->expr_join_nest;
+ emb_join_list= &emb_tbl_nest->nested_join->join_list;
+ }
+ else if (!subq_pred->expr_join_nest->outer_join)
+ {
+ /*
+ We're dealing with
+
+ ... INNER JOIN tblX ON (subquery AND whatever) ...
+
+ The sj-nest will be tblX's "sibling", i.e. another child of its
+ parent. This is ok because tblX is joined as an inner join.
+ */
+ emb_tbl_nest= subq_pred->expr_join_nest->embedding;
+ if (emb_tbl_nest)
+ emb_join_list= &emb_tbl_nest->nested_join->join_list;
+ }
+ else if (!subq_pred->expr_join_nest->nested_join)
+ {
+ TABLE_LIST *outer_tbl= subq_pred->expr_join_nest;
+ TABLE_LIST *wrap_nest;
+ /*
+ We're dealing with
+
+ ... LEFT JOIN tbl ON (on_expr AND subq_pred) ...
+
+ we'll need to convert it into:
+
+ ... LEFT JOIN ( tbl SJ (subq_tables) ) ON (on_expr AND subq_pred) ...
+ | |
+ |<----- wrap_nest ---->|
+
+ Q: other subqueries may be pointing to this element. What to do?
+ A1: simple solution: copy *subq_pred->expr_join_nest= *parent_nest.
+ But we'll need to fix other pointers.
+ A2: Another way: have TABLE_LIST::next_ptr so the following
+ subqueries know the table has been nested.
+ A3: changes in the TABLE_LIST::outer_join will make everything work
+ automatically.
+ */
+ if (!(wrap_nest= alloc_join_nest(parent_join->thd)))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ wrap_nest->embedding= outer_tbl->embedding;
+ wrap_nest->join_list= outer_tbl->join_list;
+ wrap_nest->alias= (char*) "(sj-wrap)";
+
+ wrap_nest->nested_join->join_list.empty();
+ wrap_nest->nested_join->join_list.push_back(outer_tbl);
+
+ outer_tbl->embedding= wrap_nest;
+ outer_tbl->join_list= &wrap_nest->nested_join->join_list;
+
+ /*
+ wrap_nest will take place of outer_tbl, so move the outer join flag
+ and on_expr
+ */
+ wrap_nest->outer_join= outer_tbl->outer_join;
+ outer_tbl->outer_join= 0;
+
+ wrap_nest->on_expr= outer_tbl->on_expr;
+ outer_tbl->on_expr= NULL;
+
+ List_iterator<TABLE_LIST> li(*wrap_nest->join_list);
+ TABLE_LIST *tbl;
+ while ((tbl= li++))
+ {
+ if (tbl == outer_tbl)
+ {
+ li.replace(wrap_nest);
+ break;
+ }
+ }
+ /*
+ Ok now wrap_nest 'contains' outer_tbl and we're ready to add the
+ semi-join nest into it
+ */
+ emb_join_list= &wrap_nest->nested_join->join_list;
+ emb_tbl_nest= wrap_nest;
+ }
+ }
+
+ TABLE_LIST *sj_nest;
+ NESTED_JOIN *nested_join;
+ if (!(sj_nest= alloc_join_nest(parent_join->thd)))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ nested_join= sj_nest->nested_join;
+
+ sj_nest->join_list= emb_join_list;
+ sj_nest->embedding= emb_tbl_nest;
+ sj_nest->alias= (char*) "(sj-nest)";
+ sj_nest->sj_subq_pred= subq_pred;
+ /* Nests do not participate in those 'chains', so: */
+ /* sj_nest->next_leaf= sj_nest->next_local= sj_nest->next_global == NULL*/
+ emb_join_list->push_back(sj_nest);
+
+ /*
+ nested_join->used_tables and nested_join->not_null_tables are
+ initialized in simplify_joins().
+ */
+
+ /*
+ 2. Walk through subquery's top list and set 'embedding' to point to the
+ sj-nest.
+ */
+ st_select_lex *subq_lex= subq_pred->unit->first_select();
+ nested_join->join_list.empty();
+ List_iterator_fast<TABLE_LIST> li(subq_lex->top_join_list);
+ TABLE_LIST *tl, *last_leaf;
+ while ((tl= li++))
+ {
+ tl->embedding= sj_nest;
+ tl->join_list= &nested_join->join_list;
+ nested_join->join_list.push_back(tl);
+ }
+
+ /*
+ Reconnect the next_leaf chain.
+ TODO: Do we have to put subquery's tables at the end of the chain?
+ Inserting them at the beginning would be a bit faster.
+ NOTE: We actually insert them at the front! That's because the order is
+ reversed in this list.
+ */
+ for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf) ;
+ tl->next_leaf= subq_lex->leaf_tables;
+ last_leaf= tl;
+
+ /*
+ Same as above for next_local chain
+ (a theory: a next_local chain always starts with ::leaf_tables
+ because view's tables are inserted after the view)
+ */
+ for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local) ;
+ tl->next_local= subq_lex->leaf_tables;
+
+ /* A theory: no need to re-connect the next_global chain */
+
+ /* 3. Remove the original subquery predicate from the WHERE/ON */
+
+ // The subqueries were replaced for Item_int(1) earlier
+ subq_pred->exec_method=
+ Item_in_subselect::SEMI_JOIN; // for subsequent executions
+ /*TODO: also reset the 'with_subselect' there. */
+
+ /* n. Adjust the parent_join->tables counter */
+ uint table_no= parent_join->tables;
+ /* n. Walk through child's tables and adjust table->map */
+ for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++)
+ {
+ tl->table->tablenr= table_no;
+ tl->table->map= ((table_map)1) << table_no;
+ SELECT_LEX *old_sl= tl->select_lex;
+ tl->select_lex= parent_join->select_lex;
+ for (TABLE_LIST *emb= tl->embedding;
+ emb && emb->select_lex == old_sl;
+ emb= emb->embedding)
+ emb->select_lex= parent_join->select_lex;
+ }
+ parent_join->tables += subq_lex->join->tables;
+
+ /*
+ Put the subquery's WHERE into semi-join's sj_on_expr
+ Add the subquery-induced equalities too.
+ */
+ SELECT_LEX *save_lex= thd->lex->current_select;
+ thd->lex->current_select=subq_lex;
+ if (!subq_pred->left_expr->fixed &&
+ subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
+ DBUG_RETURN(TRUE);
+ thd->lex->current_select=save_lex;
+
+ sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
+ sj_nest->nested_join->sj_depends_on= subq_pred->used_tables() |
+ subq_pred->left_expr->used_tables();
+ sj_nest->sj_on_expr= subq_lex->join->conds;
+
+ /*
+ Create the IN-equalities and inject them into semi-join's ON expression.
+ Additionally, for LooseScan strategy
+ - Record the number of IN-equalities.
+ - Create list of pointers to (oe1, ..., ieN). We'll need the list to
+ see which of the expressions are bound and which are not (for those
+ we'll produce a distinct stream of (ie_i1,...ie_ik).
+
+ (TODO: can we just create a list of pointers and hope the expressions
+ will not substitute themselves on fix_fields()? or we need to wrap
+ them into Item_direct_view_refs and store pointers to those. The
+ pointers to Item_direct_view_refs are guaranteed to be stable as
+ Item_direct_view_refs doesn't substitute itself with anything in
+ Item_direct_view_ref::fix_fields.
+ */
+ sj_nest->sj_in_exprs= subq_pred->left_expr->cols();
+ sj_nest->nested_join->sj_outer_expr_list.empty();
+
+ if (subq_pred->left_expr->cols() == 1)
+ {
+ nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr);
+ Item_func_eq *item_eq=
+ new Item_func_eq(subq_pred->left_expr, subq_lex->ref_pointer_array[0]);
+ item_eq->in_equality_no= 0;
+ sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
+ }
+ else
+ {
+ for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
+ {
+ nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr->
+ element_index(i));
+ Item_func_eq *item_eq=
+ new Item_func_eq(subq_pred->left_expr->element_index(i),
+ subq_lex->ref_pointer_array[i]);
+ item_eq->in_equality_no= i;
+ sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
+ }
+ }
+ /* Fix the created equality and AND */
+ sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr);
+
+ /*
+ Walk through sj nest's WHERE and ON expressions and call
+ item->fix_table_changes() for all items.
+ */
+ sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr);
+ fix_list_after_tbl_changes(parent_lex, &sj_nest->nested_join->join_list);
+
+
+ /* Unlink the child select_lex so it doesn't show up in EXPLAIN: */
+ subq_lex->master_unit()->exclude_level();
+
+ DBUG_EXECUTE("where",
+ print_where(sj_nest->sj_on_expr,"SJ-EXPR", QT_ORDINARY););
+
+ /* Inject sj_on_expr into the parent's WHERE or ON */
+ if (emb_tbl_nest)
+ {
+ emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
+ sj_nest->sj_on_expr);
+ emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
+ }
+ else
+ {
+ /* Inject into the WHERE */
+ parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
+ parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
+ parent_join->select_lex->where= parent_join->conds;
+ }
+
+ if (subq_lex->ftfunc_list->elements)
+ {
+ Item_func_match *ifm;
+ List_iterator_fast<Item_func_match> li(*(subq_lex->ftfunc_list));
+ while ((ifm= li++))
+ parent_lex->ftfunc_list->push_front(ifm);
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+static TABLE_LIST *alloc_join_nest(THD *thd)
+{
+ TABLE_LIST *tbl;
+ if (!(tbl= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
+ sizeof(NESTED_JOIN))))
+ return NULL;
+ tbl->nested_join= (NESTED_JOIN*) ((uchar*)tbl +
+ ALIGN_SIZE(sizeof(TABLE_LIST)));
+ return tbl;
+}
+
+
+static
+void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
+{
+ List_iterator<TABLE_LIST> it(*tlist);
+ TABLE_LIST *table;
+ while ((table= it++))
+ {
+ if (table->on_expr)
+ table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
+ if (table->nested_join)
+ fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list);
+ }
+}
+
+
+/*
+ Pull tables out of semi-join nests, if possible
+
+ SYNOPSIS
+ pull_out_semijoin_tables()
+ join The join where to do the semi-join flattening
+
+ DESCRIPTION
+ Try to pull tables out of semi-join nests.
+
+ PRECONDITIONS
+ When this function is called, the join may have several semi-join nests
+ but it is guaranteed that one semi-join nest does not contain another.
+
+ ACTION
+ A table can be pulled out of the semi-join nest if
+ - It is a constant table, or
+ - It is accessed via eq_ref(outer_tables)
+
+ POSTCONDITIONS
+ * Tables that were pulled out have JOIN_TAB::emb_sj_nest == NULL
+ * Tables that were not pulled out have JOIN_TAB::emb_sj_nest pointing
+ to semi-join nest they are in.
+ * Semi-join nests' TABLE_LIST::sj_inner_tables is updated accordingly
+
+ This operation is (and should be) performed at each PS execution since
+ tables may become/cease to be constant across PS reexecutions.
+
+ NOTE
+ Table pullout may make uncorrelated subquery correlated. Consider this
+ example:
+
+ ... WHERE oe IN (SELECT it1.primary_key WHERE p(it1, it2) ... )
+
+ here table it1 can be pulled out (we have it1.primary_key=oe which gives
+ us functional dependency). Once it1 is pulled out, all references to it1
+ from p(it1, it2) become references to outside of the subquery and thus
+ make the subquery (i.e. its semi-join nest) correlated.
+ Making the subquery (i.e. its semi-join nest) correlated prevents us from
+ using Materialization or LooseScan to execute it.
+
+ RETURN
+ 0 - OK
+ 1 - Out of memory error
+*/
+
+int pull_out_semijoin_tables(JOIN *join)
+{
+ TABLE_LIST *sj_nest;
+ DBUG_ENTER("pull_out_semijoin_tables");
+ List_iterator<TABLE_LIST> sj_list_it(join->select_lex->sj_nests);
+
+ /* Try pulling out of the each of the semi-joins */
+ while ((sj_nest= sj_list_it++))
+ {
+ /* Action #1: Mark the constant tables to be pulled out */
+ table_map pulled_tables= 0;
+ List_iterator<TABLE_LIST> child_li(sj_nest->nested_join->join_list);
+ TABLE_LIST *tbl;
+ while ((tbl= child_li++))
+ {
+ if (tbl->table)
+ {
+ tbl->table->reginfo.join_tab->emb_sj_nest= sj_nest;
+#if 0
+ /*
+ Do not pull out tables because they are constant. This operation has
+ a problem:
+ - Some constant tables may become/cease to be constant across PS
+ re-executions
+ - Contrary to our initial assumption, it turned out that table pullout
+ operation is not easily undoable.
+
+ The solution is to leave constant tables where they are. This will
+ affect only constant tables that are 1-row or empty, tables that are
+ constant because they are accessed via eq_ref(const) access will
+ still be pulled out as functionally-dependent.
+
+ This will cause us to miss the chance to flatten some of the
+ subqueries, but since const tables do not generate many duplicates,
+ it really doesn't matter that much whether they were pulled out or
+ not.
+
+ All of this was done as fix for BUG#43768.
+ */
+ if (tbl->table->map & join->const_table_map)
+ {
+ pulled_tables |= tbl->table->map;
+ DBUG_PRINT("info", ("Table %s pulled out (reason: constant)",
+ tbl->table->alias));
+ }
+#endif
+ }
+ }
+
+ /*
+ Action #2: Find which tables we can pull out based on
+ update_ref_and_keys() data. Note that pulling one table out can allow
+ us to pull out some other tables too.
+ */
+ bool pulled_a_table;
+ do
+ {
+ pulled_a_table= FALSE;
+ child_li.rewind();
+ while ((tbl= child_li++))
+ {
+ if (tbl->table && !(pulled_tables & tbl->table->map))
+ {
+ if (find_eq_ref_candidate(tbl->table,
+ sj_nest->nested_join->used_tables &
+ ~pulled_tables))
+ {
+ pulled_a_table= TRUE;
+ pulled_tables |= tbl->table->map;
+ DBUG_PRINT("info", ("Table %s pulled out (reason: func dep)",
+ tbl->table->alias.c_ptr()));
+ /*
+ Pulling a table out of uncorrelated subquery in general makes
+ makes it correlated. See the NOTE to this funtion.
+ */
+ sj_nest->sj_subq_pred->is_correlated= TRUE;
+ sj_nest->nested_join->sj_corr_tables|= tbl->table->map;
+ sj_nest->nested_join->sj_depends_on|= tbl->table->map;
+ }
+ }
+ }
+ } while (pulled_a_table);
+
+ child_li.rewind();
+ /*
+ Action #3: Move the pulled out TABLE_LIST elements to the parents.
+ */
+ table_map inner_tables= sj_nest->nested_join->used_tables &
+ ~pulled_tables;
+ /* Record the bitmap of inner tables */
+ sj_nest->sj_inner_tables= inner_tables;
+ if (pulled_tables)
+ {
+ List<TABLE_LIST> *upper_join_list= (sj_nest->embedding != NULL)?
+ (&sj_nest->embedding->nested_join->join_list):
+ (&join->select_lex->top_join_list);
+ Query_arena *arena, backup;
+ arena= join->thd->activate_stmt_arena_if_needed(&backup);
+ while ((tbl= child_li++))
+ {
+ if (tbl->table)
+ {
+ if (inner_tables & tbl->table->map)
+ {
+ /* This table is not pulled out */
+ tbl->table->reginfo.join_tab->emb_sj_nest= sj_nest;
+ }
+ else
+ {
+ /* This table has been pulled out of the semi-join nest */
+ tbl->table->reginfo.join_tab->emb_sj_nest= NULL;
+ /*
+ Pull the table up in the same way as simplify_joins() does:
+ update join_list and embedding pointers but keep next[_local]
+ pointers.
+ */
+ child_li.remove();
+ sj_nest->nested_join->used_tables &= ~tbl->table->map;
+ upper_join_list->push_back(tbl);
+ tbl->join_list= upper_join_list;
+ tbl->embedding= sj_nest->embedding;
+ }
+ }
+ }
+
+ /* Remove the sj-nest itself if we've removed everything from it */
+ if (!inner_tables)
+ {
+ List_iterator<TABLE_LIST> li(*upper_join_list);
+ /* Find the sj_nest in the list. */
+ while (sj_nest != li++) ;
+ li.remove();
+ /* Also remove it from the list of SJ-nests: */
+ sj_list_it.remove();
+ }
+
+ if (arena)
+ join->thd->restore_active_arena(arena, &backup);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Optimize semi-join nests that could be run with sj-materialization
+
+ SYNOPSIS
+ optimize_semijoin_nests()
+ join The join to optimize semi-join nests for
+ all_table_map Bitmap of all tables in the join
+
+ DESCRIPTION
+ Optimize each of the semi-join nests that can be run with
+ materialization. For each of the nests, we
+ - Generate the best join order for this "sub-join" and remember it;
+ - Remember the sub-join execution cost (it's part of materialization
+ cost);
+ - Calculate other costs that will be incurred if we decide
+ to use materialization strategy for this semi-join nest.
+
+ All obtained information is saved and will be used by the main join
+ optimization pass.
+
+ RETURN
+ FALSE Ok
+ TRUE Out of memory error
+*/
+
+bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
+{
+ DBUG_ENTER("optimize_semijoin_nests");
+ List_iterator<TABLE_LIST> sj_list_it(join->select_lex->sj_nests);
+ TABLE_LIST *sj_nest;
+ while ((sj_nest= sj_list_it++))
+ {
+ /* semi-join nests with only constant tables are not valid */
+ /// DBUG_ASSERT(sj_nest->sj_inner_tables & ~join->const_table_map);
+
+ sj_nest->sj_mat_info= NULL;
+ /*
+ The statement may have been executed with 'semijoin=on' earlier.
+ We need to verify that 'semijoin=on' still holds.
+ */
+ if (optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN) &&
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_MATERIALIZATION))
+ {
+ if ((sj_nest->sj_inner_tables & ~join->const_table_map) && /* not everything was pulled out */
+ !sj_nest->sj_subq_pred->is_correlated &&
+ sj_nest->sj_subq_pred->types_allow_materialization)
+ {
+ join->emb_sjm_nest= sj_nest;
+ if (choose_plan(join, all_table_map))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ /*
+ The best plan to run the subquery is now in join->best_positions,
+ save it.
+ */
+ uint n_tables= my_count_bits(sj_nest->sj_inner_tables & ~join->const_table_map);
+ SJ_MATERIALIZATION_INFO* sjm;
+ if (!(sjm= new SJ_MATERIALIZATION_INFO) ||
+ !(sjm->positions= (POSITION*)join->thd->alloc(sizeof(POSITION)*
+ n_tables)))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ sjm->tables= n_tables;
+ sjm->is_used= FALSE;
+ double subjoin_out_rows, subjoin_read_time;
+ get_partial_join_cost(join, n_tables,
+ &subjoin_read_time, &subjoin_out_rows);
+
+ sjm->materialization_cost.convert_from_cost(subjoin_read_time);
+ sjm->rows= subjoin_out_rows;
+
+ List<Item> &right_expr_list=
+ sj_nest->sj_subq_pred->unit->first_select()->item_list;
+ /*
+ Adjust output cardinality estimates. If the subquery has form
+
+ ... oe IN (SELECT t1.colX, t2.colY, func(X,Y,Z) )
+
+ then the number of distinct output record combinations has an
+ upper bound of product of number of records matching the tables
+ that are used by the SELECT clause.
+ TODO:
+ We can get a more precise estimate if we
+ - use rec_per_key cardinality estimates. For simple cases like
+ "oe IN (SELECT t.key ...)" it is trivial.
+ - Functional dependencies between the tables in the semi-join
+ nest (the payoff is probably less here?)
+ */
+ {
+ for (uint i=0 ; i < join->const_tables + sjm->tables ; i++)
+ {
+ JOIN_TAB *tab= join->best_positions[i].table;
+ join->map2table[tab->table->tablenr]= tab;
+ }
+ List_iterator<Item> it(right_expr_list);
+ Item *item;
+ table_map map= 0;
+ while ((item= it++))
+ map |= item->used_tables();
+ map= map & ~PSEUDO_TABLE_BITS;
+ Table_map_iterator tm_it(map);
+ int tableno;
+ double rows= 1.0;
+ while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
+ rows *= join->map2table[tableno]->table->quick_condition_rows;
+ sjm->rows= min(sjm->rows, rows);
+ }
+ memcpy(sjm->positions, join->best_positions + join->const_tables,
+ sizeof(POSITION) * n_tables);
+
+ /*
+ Calculate temporary table parameters and usage costs
+ */
+ uint rowlen= get_tmp_table_rec_length(right_expr_list);
+ double lookup_cost;
+ if (rowlen * subjoin_out_rows< join->thd->variables.max_heap_table_size)
+ lookup_cost= HEAP_TEMPTABLE_LOOKUP_COST;
+ else
+ lookup_cost= DISK_TEMPTABLE_LOOKUP_COST;
+
+ /*
+ Let materialization cost include the cost to write the data into the
+ temporary table:
+ */
+ sjm->materialization_cost.add_io(subjoin_out_rows, lookup_cost);
+
+ /*
+ Set the cost to do a full scan of the temptable (will need this to
+ consider doing sjm-scan):
+ */
+ sjm->scan_cost.zero();
+ sjm->scan_cost.add_io(sjm->rows, lookup_cost);
+
+ sjm->lookup_cost.convert_from_cost(lookup_cost);
+ sj_nest->sj_mat_info= sjm;
+ DBUG_EXECUTE("opt", print_sjm(sjm););
+ }
+ }
+ }
+ join->emb_sjm_nest= NULL;
+ DBUG_RETURN(FALSE);
+}
+
+/*
+ Get estimated record length for semi-join materialization temptable
+
+ SYNOPSIS
+ get_tmp_table_rec_length()
+ items IN subquery's select list.
+
+ DESCRIPTION
+ Calculate estimated record length for semi-join materialization
+ temptable. It's an estimate because we don't follow every bit of
+ create_tmp_table()'s logic. This isn't necessary as the return value of
+ this function is used only for cost calculations.
+
+ RETURN
+ Length of the temptable record, in bytes
+*/
+
+static uint get_tmp_table_rec_length(List<Item> &items)
+{
+ uint len= 0;
+ Item *item;
+ List_iterator<Item> it(items);
+ while ((item= it++))
+ {
+ switch (item->result_type()) {
+ case REAL_RESULT:
+ len += sizeof(double);
+ break;
+ case INT_RESULT:
+ if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
+ len += 8;
+ else
+ len += 4;
+ break;
+ case STRING_RESULT:
+ enum enum_field_types type;
+ /* DATE/TIME and GEOMETRY fields have STRING_RESULT result type. */
+ if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
+ type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
+ type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY)
+ len += 8;
+ else
+ len += item->max_length;
+ break;
+ case DECIMAL_RESULT:
+ len += 10;
+ break;
+ case ROW_RESULT:
+ default:
+ DBUG_ASSERT(0); /* purecov: deadcode */
+ break;
+ }
+ }
+ return len;
+}
+
+//psergey-todo: is the below a kind of table elimination??
+/*
+ Check if table's KEYUSE elements have an eq_ref(outer_tables) candidate
+
+ SYNOPSIS
+ find_eq_ref_candidate()
+ table Table to be checked
+ sj_inner_tables Bitmap of inner tables. eq_ref(inner_table) doesn't
+ count.
+
+ DESCRIPTION
+ Check if table's KEYUSE elements have an eq_ref(outer_tables) candidate
+
+ TODO
+ Check again if it is feasible to factor common parts with constant table
+ search
+
+ RETURN
+ TRUE - There exists an eq_ref(outer-tables) candidate
+ FALSE - Otherwise
+*/
+
+bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
+{
+ KEYUSE *keyuse= table->reginfo.join_tab->keyuse;
+ uint key;
+
+ if (keyuse)
+ {
+ while (1) /* For each key */
+ {
+ key= keyuse->key;
+ KEY *keyinfo= table->key_info + key;
+ key_part_map bound_parts= 0;
+ if (keyinfo->flags & HA_NOSAME)
+ {
+ do /* For all equalities on all key parts */
+ {
+ /* Check if this is "t.keypart = expr(outer_tables) */
+ if (!(keyuse->used_tables & sj_inner_tables) &&
+ !(keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL))
+ {
+ bound_parts |= 1 << keyuse->keypart;
+ }
+ keyuse++;
+ } while (keyuse->key == key && keyuse->table == table);
+
+ if (bound_parts == PREV_BITS(uint, keyinfo->key_parts))
+ return TRUE;
+ if (keyuse->table != table)
+ return FALSE;
+ }
+ else
+ {
+ do
+ {
+ keyuse++;
+ if (keyuse->table != table)
+ return FALSE;
+ }
+ while (keyuse->key == key);
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*
+ Do semi-join optimization step after we've added a new tab to join prefix
+
+ SYNOPSIS
+ advance_sj_state()
+ join The join we're optimizing
+ remaining_tables Tables not in the join prefix
+ new_join_tab Join tab we've just added to the join prefix
+ idx Index of this join tab (i.e. number of tables
+ in the prefix minus one)
+ current_record_count INOUT Estimate of #records in join prefix's output
+ current_read_time INOUT Cost to execute the join prefix
+ loose_scan_pos IN A POSITION with LooseScan plan to access
+ table new_join_tab
+ (produced by the last best_access_path call)
+
+ DESCRIPTION
+ Update semi-join optimization state after we've added another tab (table
+ and access method) to the join prefix.
+
+ The state is maintained in join->positions[#prefix_size]. Each of the
+ available strategies has its own state variables.
+
+ for each semi-join strategy
+ {
+ update strategy's state variables;
+
+ if (join prefix has all the tables that are needed to consider
+ using this strategy for the semi-join(s))
+ {
+ calculate cost of using the strategy
+ if ((this is the first strategy to handle the semi-join nest(s) ||
+ the cost is less than other strategies))
+ {
+ // Pick this strategy
+ pos->sj_strategy= ..
+ ..
+ }
+ }
+
+ Most of the new state is saved join->positions[idx] (and hence no undo
+ is necessary). Several members of class JOIN are updated also, these
+ changes can be rolled back with restore_prev_sj_state().
+
+ See setup_semijoin_dups_elimination() for a description of what kinds of
+ join prefixes each strategy can handle.
+*/
+
+void advance_sj_state(JOIN *join, table_map remaining_tables,
+ const JOIN_TAB *new_join_tab, uint idx,
+ double *current_record_count, double *current_read_time,
+ POSITION *loose_scan_pos)
+{
+ TABLE_LIST *emb_sj_nest;
+ POSITION *pos= join->positions + idx;
+ remaining_tables &= ~new_join_tab->table->map;
+
+ pos->prefix_cost.convert_from_cost(*current_read_time);
+ pos->prefix_record_count= *current_record_count;
+ pos->sj_strategy= SJ_OPT_NONE;
+
+ /* Initialize the state or copy it from prev. tables */
+ if (idx == join->const_tables)
+ {
+ pos->first_firstmatch_table= MAX_TABLES;
+ pos->first_loosescan_table= MAX_TABLES;
+ pos->dupsweedout_tables= 0;
+ pos->sjm_scan_need_tables= 0;
+ LINT_INIT(pos->sjm_scan_last_inner);
+ }
+ else
+ {
+ // FirstMatch
+ pos->first_firstmatch_table=
+ (pos[-1].sj_strategy == SJ_OPT_FIRST_MATCH) ?
+ MAX_TABLES : pos[-1].first_firstmatch_table;
+ pos->first_firstmatch_rtbl= pos[-1].first_firstmatch_rtbl;
+ pos->firstmatch_need_tables= pos[-1].firstmatch_need_tables;
+
+ // LooseScan
+ pos->first_loosescan_table=
+ (pos[-1].sj_strategy == SJ_OPT_LOOSE_SCAN) ?
+ MAX_TABLES : pos[-1].first_loosescan_table;
+ pos->loosescan_need_tables= pos[-1].loosescan_need_tables;
+
+ // SJ-Materialization Scan
+ pos->sjm_scan_need_tables=
+ (pos[-1].sj_strategy == SJ_OPT_MATERIALIZE_SCAN) ?
+ 0 : pos[-1].sjm_scan_need_tables;
+ pos->sjm_scan_last_inner= pos[-1].sjm_scan_last_inner;
+
+ // Duplicate Weedout
+ pos->dupsweedout_tables= pos[-1].dupsweedout_tables;
+ pos->first_dupsweedout_table= pos[-1].first_dupsweedout_table;
+ }
+
+ table_map handled_by_fm_or_ls= 0;
+ /* FirstMatch Strategy */
+ if (new_join_tab->emb_sj_nest &&
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_FIRSTMATCH))
+ {
+ const table_map outer_corr_tables=
+ new_join_tab->emb_sj_nest->nested_join->sj_corr_tables |
+ new_join_tab->emb_sj_nest->nested_join->sj_depends_on;
+ const table_map sj_inner_tables=
+ new_join_tab->emb_sj_nest->sj_inner_tables & ~join->const_table_map;
+
+ /*
+ Enter condition:
+ 1. The next join tab belongs to semi-join nest
+ (verified for the encompassing code block above).
+ 2. We're not in a duplicate producer range yet
+ 3. All outer tables that
+ - the subquery is correlated with, or
+ - referred to from the outer_expr
+ are in the join prefix
+ 4. All inner tables are still part of remaining_tables.
+ */
+ if (!join->cur_sj_inner_tables && // (2)
+ !(remaining_tables & outer_corr_tables) && // (3)
+ (sj_inner_tables == // (4)
+ ((remaining_tables | new_join_tab->table->map) & sj_inner_tables)))
+ {
+ /* Start tracking potential FirstMatch range */
+ pos->first_firstmatch_table= idx;
+ pos->firstmatch_need_tables= sj_inner_tables;
+ pos->first_firstmatch_rtbl= remaining_tables;
+ }
+
+ if (pos->first_firstmatch_table != MAX_TABLES)
+ {
+ if (outer_corr_tables & pos->first_firstmatch_rtbl)
+ {
+ /*
+ Trying to add an sj-inner table whose sj-nest has an outer correlated
+ table that was not in the prefix. This means FirstMatch can't be used.
+ */
+ pos->first_firstmatch_table= MAX_TABLES;
+ }
+ else
+ {
+ /* Record that we need all of this semi-join's inner tables, too */
+ pos->firstmatch_need_tables|= sj_inner_tables;
+ }
+
+ if (!(pos->firstmatch_need_tables & remaining_tables))
+ {
+ /*
+ Got a complete FirstMatch range.
+ Calculate correct costs and fanout
+ */
+ optimize_wo_join_buffering(join, pos->first_firstmatch_table, idx,
+ remaining_tables, FALSE, idx,
+ current_record_count,
+ current_read_time);
+ /*
+ We don't yet know what are the other strategies, so pick the
+ FirstMatch.
+
+ We ought to save the alternate POSITIONs produced by
+ optimize_wo_join_buffering but the problem is that providing save
+ space uses too much space. Instead, we will re-calculate the
+ alternate POSITIONs after we've picked the best QEP.
+ */
+ pos->sj_strategy= SJ_OPT_FIRST_MATCH;
+ handled_by_fm_or_ls= pos->firstmatch_need_tables;
+ }
+ }
+ }
+
+ /* LooseScan Strategy */
+ {
+ POSITION *first=join->positions+pos->first_loosescan_table;
+ /*
+ LooseScan strategy can't handle interleaving between tables from the
+ semi-join that LooseScan is handling and any other tables.
+
+ If we were considering LooseScan for the join prefix (1)
+ and the table we're adding creates an interleaving (2)
+ then
+ stop considering loose scan
+ */
+ if ((pos->first_loosescan_table != MAX_TABLES) && // (1)
+ (first->table->emb_sj_nest->sj_inner_tables & remaining_tables) && //(2)
+ new_join_tab->emb_sj_nest != first->table->emb_sj_nest) //(2)
+ {
+ pos->first_loosescan_table= MAX_TABLES;
+ }
+
+ /*
+ If we got an option to use LooseScan for the current table, start
+ considering using LooseScan strategy
+ */
+ if (loose_scan_pos->read_time != DBL_MAX)
+ {
+ pos->first_loosescan_table= idx;
+ pos->loosescan_need_tables=
+ new_join_tab->emb_sj_nest->sj_inner_tables |
+ new_join_tab->emb_sj_nest->nested_join->sj_depends_on |
+ new_join_tab->emb_sj_nest->nested_join->sj_corr_tables;
+ }
+
+ if ((pos->first_loosescan_table != MAX_TABLES) &&
+ !(remaining_tables & pos->loosescan_need_tables))
+ {
+ /*
+ Ok we have LooseScan plan and also have all LooseScan sj-nest's
+ inner tables and outer correlated tables into the prefix.
+ */
+
+ first=join->positions + pos->first_loosescan_table;
+ uint n_tables= my_count_bits(first->table->emb_sj_nest->sj_inner_tables);
+ /* Got a complete LooseScan range. Calculate its cost */
+ /*
+ The same problem as with FirstMatch - we need to save POSITIONs
+ somewhere but reserving space for all cases would require too
+ much space. We will re-calculate POSITION structures later on.
+ */
+ optimize_wo_join_buffering(join, pos->first_loosescan_table, idx,
+ remaining_tables,
+ TRUE, //first_alt
+ pos->first_loosescan_table + n_tables,
+ current_record_count,
+ current_read_time);
+ /*
+ We don't yet have any other strategies that could handle this
+ semi-join nest (the other options are Duplicate Elimination or
+ Materialization, which need at least the same set of tables in
+ the join prefix to be considered) so unconditionally pick the
+ LooseScan.
+ */
+ pos->sj_strategy= SJ_OPT_LOOSE_SCAN;
+ handled_by_fm_or_ls= first->table->emb_sj_nest->sj_inner_tables;
+ }
+ }
+
+ /*
+ Update join->cur_sj_inner_tables (Used by FirstMatch in this function and
+ LooseScan detector in best_access_path)
+ */
+ if ((emb_sj_nest= new_join_tab->emb_sj_nest))
+ {
+ join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;
+ join->cur_dups_producing_tables |= emb_sj_nest->sj_inner_tables;
+
+ /* Remove the sj_nest if all of its SJ-inner tables are in cur_table_map */
+ if (!(remaining_tables &
+ emb_sj_nest->sj_inner_tables & ~new_join_tab->table->map))
+ join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
+ }
+ join->cur_dups_producing_tables &= ~handled_by_fm_or_ls;
+
+ /* 4. SJ-Materialization and SJ-Materialization-scan strategy handler */
+ bool sjm_scan;
+ SJ_MATERIALIZATION_INFO *mat_info;
+ if ((mat_info= at_sjmat_pos(join, remaining_tables,
+ new_join_tab, idx, &sjm_scan)))
+ {
+ if (sjm_scan)
+ {
+ /*
+ We can't yet evaluate this option yet. This is because we can't
+ accout for fanout of sj-inner tables yet:
+
+ ntX SJM-SCAN(it1 ... itN) | ot1 ... otN |
+ ^(1) ^(2)
+
+ we're now at position (1). SJM temptable in general has multiple
+ records, so at point (1) we'll get the fanout from sj-inner tables (ie
+ there will be multiple record combinations).
+
+ The final join result will not contain any semi-join produced
+ fanout, i.e. tables within SJM-SCAN(...) will not contribute to
+ the cardinality of the join output. Extra fanout produced by
+ SJM-SCAN(...) will be 'absorbed' into fanout produced by ot1 ... otN.
+
+ The simple way to model this is to remove SJM-SCAN(...) fanout once
+ we reach the point #2.
+ */
+ pos->sjm_scan_need_tables=
+ new_join_tab->emb_sj_nest->sj_inner_tables |
+ new_join_tab->emb_sj_nest->nested_join->sj_depends_on |
+ new_join_tab->emb_sj_nest->nested_join->sj_corr_tables;
+ pos->sjm_scan_last_inner= idx;
+ }
+ else
+ {
+ /* This is SJ-Materialization with lookups */
+ COST_VECT prefix_cost;
+ signed int first_tab= (int)idx - mat_info->tables;
+ double prefix_rec_count;
+ if (first_tab < (int)join->const_tables)
+ {
+ prefix_cost.zero();
+ prefix_rec_count= 1.0;
+ }
+ else
+ {
+ prefix_cost= join->positions[first_tab].prefix_cost;
+ prefix_rec_count= join->positions[first_tab].prefix_record_count;
+ }
+
+ double mat_read_time= prefix_cost.total_cost();
+ mat_read_time += mat_info->materialization_cost.total_cost() +
+ prefix_rec_count * mat_info->lookup_cost.total_cost();
+
+ if (mat_read_time < *current_read_time || join->cur_dups_producing_tables)
+ {
+ /*
+ NOTE: When we pick to use SJM[-Scan] we don't memcpy its POSITION
+ elements to join->positions as that makes it hard to return things
+ back when making one step back in join optimization. That's done
+ after the QEP has been chosen.
+ */
+ pos->sj_strategy= SJ_OPT_MATERIALIZE;
+ *current_read_time= mat_read_time;
+ *current_record_count= prefix_rec_count;
+ join->cur_dups_producing_tables&=
+ ~new_join_tab->emb_sj_nest->sj_inner_tables;
+ }
+ }
+ }
+
+ /* 4.A SJM-Scan second phase check */
+ if (pos->sjm_scan_need_tables && /* Have SJM-Scan prefix */
+ !(pos->sjm_scan_need_tables & remaining_tables))
+ {
+ TABLE_LIST *mat_nest=
+ join->positions[pos->sjm_scan_last_inner].table->emb_sj_nest;
+ SJ_MATERIALIZATION_INFO *mat_info= mat_nest->sj_mat_info;
+
+ double prefix_cost;
+ double prefix_rec_count;
+ int first_tab= pos->sjm_scan_last_inner + 1 - mat_info->tables;
+ /* Get the prefix cost */
+ if (first_tab == (int)join->const_tables)
+ {
+ prefix_rec_count= 1.0;
+ prefix_cost= 0.0;
+ }
+ else
+ {
+ prefix_cost= join->positions[first_tab - 1].prefix_cost.total_cost();
+ prefix_rec_count= join->positions[first_tab - 1].prefix_record_count;
+ }
+
+ /* Add materialization cost */
+ prefix_cost += mat_info->materialization_cost.total_cost() +
+ prefix_rec_count * mat_info->scan_cost.total_cost();
+ prefix_rec_count *= mat_info->rows;
+
+ uint i;
+ table_map rem_tables= remaining_tables;
+ for (i= idx; i != (first_tab + mat_info->tables - 1); i--)
+ rem_tables |= join->positions[i].table->table->map;
+
+ POSITION curpos, dummy;
+ /* Need to re-run best-access-path as we prefix_rec_count has changed */
+ for (i= first_tab + mat_info->tables; i <= idx; i++)
+ {
+ best_access_path(join, join->positions[i].table, rem_tables, i, FALSE,
+ prefix_rec_count, &curpos, &dummy);
+ prefix_rec_count *= curpos.records_read;
+ prefix_cost += curpos.read_time;
+ }
+
+ /*
+ Use the strategy if
+ * it is cheaper then what we've had, or
+ * we haven't picked any other semi-join strategy yet
+ In the second case, we pick this strategy unconditionally because
+ comparing cost without semi-join duplicate removal with cost with
+ duplicate removal is not an apples-to-apples comparison.
+ */
+ if (prefix_cost < *current_read_time || join->cur_dups_producing_tables)
+ {
+ pos->sj_strategy= SJ_OPT_MATERIALIZE_SCAN;
+ *current_read_time= prefix_cost;
+ *current_record_count= prefix_rec_count;
+ join->cur_dups_producing_tables&= ~mat_nest->sj_inner_tables;
+
+ }
+ }
+
+ /* 5. Duplicate Weedout strategy handler */
+ {
+ /*
+ Duplicate weedout can be applied after all ON-correlated and
+ correlated
+ */
+ TABLE_LIST *nest;
+ if ((nest= new_join_tab->emb_sj_nest))
+ {
+ if (!pos->dupsweedout_tables)
+ pos->first_dupsweedout_table= idx;
+
+ pos->dupsweedout_tables |= nest->sj_inner_tables |
+ nest->nested_join->sj_depends_on |
+ nest->nested_join->sj_corr_tables;
+ }
+
+ if (pos->dupsweedout_tables &&
+ !(remaining_tables &
+ ~new_join_tab->table->map & pos->dupsweedout_tables))
+ {
+ /*
+ Ok, reached a state where we could put a dups weedout point.
+ Walk back and calculate
+ - the join cost (this is needed as the accumulated cost may assume
+ some other duplicate elimination method)
+ - extra fanout that will be removed by duplicate elimination
+ - duplicate elimination cost
+ There are two cases:
+ 1. We have other strategy/ies to remove all of the duplicates.
+ 2. We don't.
+
+ We need to calculate the cost in case #2 also because we need to make
+ choice between this join order and others.
+ */
+ uint first_tab= pos->first_dupsweedout_table;
+ double dups_cost;
+ double prefix_rec_count;
+ double sj_inner_fanout= 1.0;
+ double sj_outer_fanout= 1.0;
+ uint temptable_rec_size;
+ if (first_tab == join->const_tables)
+ {
+ prefix_rec_count= 1.0;
+ temptable_rec_size= 0;
+ dups_cost= 0.0;
+ }
+ else
+ {
+ dups_cost= join->positions[first_tab - 1].prefix_cost.total_cost();
+ prefix_rec_count= join->positions[first_tab - 1].prefix_record_count;
+ temptable_rec_size= 8; /* This is not true but we'll make it so */
+ }
+
+ table_map dups_removed_fanout= 0;
+ for (uint j= pos->first_dupsweedout_table; j <= idx; j++)
+ {
+ POSITION *p= join->positions + j;
+ dups_cost += p->read_time;
+ if (p->table->emb_sj_nest)
+ {
+ sj_inner_fanout *= p->records_read;
+ dups_removed_fanout |= p->table->table->map;
+ }
+ else
+ {
+ sj_outer_fanout *= p->records_read;
+ temptable_rec_size += p->table->table->file->ref_length;
+ }
+ }
+
+ /*
+ Add the cost of temptable use. The table will have sj_outer_fanout
+ records, and we will make
+ - sj_outer_fanout table writes
+ - sj_inner_fanout*sj_outer_fanout lookups.
+
+ */
+ double one_lookup_cost;
+ if (sj_outer_fanout*temptable_rec_size >
+ join->thd->variables.max_heap_table_size)
+ one_lookup_cost= DISK_TEMPTABLE_LOOKUP_COST;
+ else
+ one_lookup_cost= HEAP_TEMPTABLE_LOOKUP_COST;
+
+ double write_cost= join->positions[first_tab].prefix_record_count*
+ sj_outer_fanout * one_lookup_cost;
+ double full_lookup_cost= join->positions[first_tab].prefix_record_count*
+ sj_outer_fanout* sj_inner_fanout *
+ one_lookup_cost;
+ dups_cost += write_cost + full_lookup_cost;
+
+ /*
+ Use the strategy if
+ * it is cheaper then what we've had, or
+ * we haven't picked any other semi-join strategy yet
+ The second part is necessary because this strategy is the last one
+ to consider (it needs "the most" tables in the prefix) and we can't
+ leave duplicate-producing tables not handled by any strategy.
+ */
+ if (dups_cost < *current_read_time || join->cur_dups_producing_tables)
+ {
+ pos->sj_strategy= SJ_OPT_DUPS_WEEDOUT;
+ *current_read_time= dups_cost;
+ *current_record_count= *current_record_count / sj_inner_fanout;
+ join->cur_dups_producing_tables &= ~dups_removed_fanout;
+ }
+ }
+ }
+}
+
+
+/*
+ Remove the last join tab from from join->cur_sj_inner_tables bitmap
+ we assume remaining_tables doesnt contain @tab.
+*/
+
+void restore_prev_sj_state(const table_map remaining_tables,
+ const JOIN_TAB *tab, uint idx)
+{
+ TABLE_LIST *emb_sj_nest;
+ if ((emb_sj_nest= tab->emb_sj_nest))
+ {
+ /* If we're removing the last SJ-inner table, remove the sj-nest */
+ if ((remaining_tables & emb_sj_nest->sj_inner_tables) ==
+ (emb_sj_nest->sj_inner_tables & ~tab->table->map))
+ {
+ tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
+ }
+ }
+}
+
+
+/*
+ Given a semi-join nest, find out which of the IN-equalities are bound
+
+ SYNOPSIS
+ get_bound_sj_equalities()
+ sj_nest Semi-join nest
+ remaining_tables Tables that are not yet bound
+
+ DESCRIPTION
+ Given a semi-join nest, find out which of the IN-equalities have their
+ left part expression bound (i.e. the said expression doesn't refer to
+ any of remaining_tables and can be evaluated).
+
+ RETURN
+ Bitmap of bound IN-equalities.
+*/
+
+ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
+ table_map remaining_tables)
+{
+ List_iterator<Item> li(sj_nest->nested_join->sj_outer_expr_list);
+ Item *item;
+ uint i= 0;
+ ulonglong res= 0;
+ while ((item= li++))
+ {
+ /*
+ Q: should this take into account equality propagation and how?
+ A: If e->outer_side is an Item_field, walk over the equality
+ class and see if there is an element that is bound?
+ (this is an optional feature)
+ */
+ if (!(item->used_tables() & remaining_tables))
+ {
+ res |= 1ULL << i;
+ }
+ }
+ return res;
+}
+
+
+/*
+ Check if the last tables of the partial join order allow to use
+ sj-materialization strategy for them
+
+ SYNOPSIS
+ at_sjmat_pos()
+ join
+ remaining_tables
+ tab the last table's join tab
+ idx last table's index
+ loose_scan OUT TRUE <=> use LooseScan
+
+ RETURN
+ TRUE Yes, can apply sj-materialization
+ FALSE No, some of the requirements are not met
+*/
+
+static SJ_MATERIALIZATION_INFO *
+at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
+ uint idx, bool *loose_scan)
+{
+ /*
+ Check if
+ 1. We're in a semi-join nest that can be run with SJ-materialization
+ 2. All the tables correlated through the IN subquery are in the prefix
+ */
+ TABLE_LIST *emb_sj_nest= tab->emb_sj_nest;
+ table_map suffix= remaining_tables & ~tab->table->map;
+ if (emb_sj_nest && emb_sj_nest->sj_mat_info &&
+ !(suffix & emb_sj_nest->sj_inner_tables))
+ {
+ /*
+ Walk back and check if all immediately preceding tables are from
+ this semi-join.
+ */
+ uint n_tables= my_count_bits(tab->emb_sj_nest->sj_inner_tables);
+ for (uint i= 1; i < n_tables ; i++)
+ {
+ if (join->positions[idx - i].table->emb_sj_nest != tab->emb_sj_nest)
+ return NULL;
+ }
+ *loose_scan= test(remaining_tables & ~tab->table->map &
+ (emb_sj_nest->sj_inner_tables |
+ emb_sj_nest->nested_join->sj_depends_on));
+ if (*loose_scan && !emb_sj_nest->sj_subq_pred->sjm_scan_allowed)
+ return NULL;
+ else
+ return emb_sj_nest->sj_mat_info;
+ }
+ return NULL;
+}
+
+
+
+/*
+ Fix semi-join strategies for the picked join order
+
+ SYNOPSIS
+ fix_semijoin_strategies_for_picked_join_order()
+ join The join with the picked join order
+
+ DESCRIPTION
+ Fix semi-join strategies for the picked join order. This is a step that
+ needs to be done right after we have fixed the join order. What we do
+ here is switch join's semi-join strategy description from backward-based
+ to forwards based.
+
+ When join optimization is in progress, we re-consider semi-join
+ strategies after we've added another table. Here's an illustration.
+ Suppose the join optimization is underway:
+
+ 1) ot1 it1 it2
+ sjX -- looking at (ot1, it1, it2) join prefix, we decide
+ to use semi-join strategy sjX.
+
+ 2) ot1 it1 it2 ot2
+ sjX sjY -- Having added table ot2, we now may consider
+ another semi-join strategy and decide to use a
+ different strategy sjY. Note that the record
+ of sjX has remained under it2. That is
+ necessary because we need to be able to get
+ back to (ot1, it1, it2) join prefix.
+ what makes things even worse is that there are cases where the choice
+ of sjY changes the way we should access it2.
+
+ 3) [ot1 it1 it2 ot2 ot3]
+ sjX sjY -- This means that after join optimization is
+ finished, semi-join info should be read
+ right-to-left (while nearly all plan refinement
+ functions, EXPLAIN, etc proceed from left to
+ right)
+
+ This function does the needed reversal, making it possible to read the
+ join and semi-join order from left to right.
+*/
+
+void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
+{
+ uint table_count=join->tables;
+ uint tablenr;
+ table_map remaining_tables= 0;
+ table_map handled_tabs= 0;
+ for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
+ {
+ POSITION *pos= join->best_positions + tablenr;
+ JOIN_TAB *s= pos->table;
+ uint first;
+ LINT_INIT(first); // Set by every branch except SJ_OPT_NONE which doesn't use it
+
+ if ((handled_tabs & s->table->map) || pos->sj_strategy == SJ_OPT_NONE)
+ {
+ remaining_tables |= s->table->map;
+ continue;
+ }
+
+ if (pos->sj_strategy == SJ_OPT_MATERIALIZE)
+ {
+ SJ_MATERIALIZATION_INFO *sjm= s->emb_sj_nest->sj_mat_info;
+ sjm->is_used= TRUE;
+ sjm->is_sj_scan= FALSE;
+ memcpy(pos - sjm->tables + 1, sjm->positions,
+ sizeof(POSITION) * sjm->tables);
+ first= tablenr - sjm->tables + 1;
+ join->best_positions[first].n_sj_tables= sjm->tables;
+ join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE;
+ }
+ else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
+ {
+ POSITION *first_inner= join->best_positions + pos->sjm_scan_last_inner;
+ SJ_MATERIALIZATION_INFO *sjm= first_inner->table->emb_sj_nest->sj_mat_info;
+ sjm->is_used= TRUE;
+ sjm->is_sj_scan= TRUE;
+ first= pos->sjm_scan_last_inner - sjm->tables + 1;
+ memcpy(join->best_positions + first,
+ sjm->positions, sizeof(POSITION) * sjm->tables);
+ join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE_SCAN;
+ join->best_positions[first].n_sj_tables= sjm->tables;
+ /*
+ Do what advance_sj_state did: re-run best_access_path for every table
+ in the [last_inner_table + 1; pos..) range
+ */
+ double prefix_rec_count;
+ /* Get the prefix record count */
+ if (first == join->const_tables)
+ prefix_rec_count= 1.0;
+ else
+ prefix_rec_count= join->best_positions[first-1].prefix_record_count;
+
+ /* Add materialization record count*/
+ prefix_rec_count *= sjm->rows;
+
+ uint i;
+ table_map rem_tables= remaining_tables;
+ for (i= tablenr; i != (first + sjm->tables - 1); i--)
+ rem_tables |= join->best_positions[i].table->table->map;
+
+ POSITION dummy;
+ join->cur_sj_inner_tables= 0;
+ for (i= first + sjm->tables; i <= tablenr; i++)
+ {
+ best_access_path(join, join->best_positions[i].table, rem_tables, i, FALSE,
+ prefix_rec_count, join->best_positions + i, &dummy);
+ prefix_rec_count *= join->best_positions[i].records_read;
+ rem_tables &= ~join->best_positions[i].table->table->map;
+ }
+ }
+
+ if (pos->sj_strategy == SJ_OPT_FIRST_MATCH)
+ {
+ first= pos->first_firstmatch_table;
+ join->best_positions[first].sj_strategy= SJ_OPT_FIRST_MATCH;
+ join->best_positions[first].n_sj_tables= tablenr - first + 1;
+ POSITION dummy; // For loose scan paths
+ double record_count= (first== join->const_tables)? 1.0:
+ join->best_positions[tablenr - 1].prefix_record_count;
+
+ table_map rem_tables= remaining_tables;
+ uint idx;
+ for (idx= first; idx <= tablenr; idx++)
+ {
+ rem_tables |= join->best_positions[idx].table->table->map;
+ }
+ /*
+ Re-run best_access_path to produce best access methods that do not use
+ join buffering
+ */
+ join->cur_sj_inner_tables= 0;
+ for (idx= first; idx <= tablenr; idx++)
+ {
+ if (join->best_positions[idx].use_join_buffer)
+ {
+ best_access_path(join, join->best_positions[idx].table,
+ rem_tables, idx, TRUE /* no jbuf */,
+ record_count, join->best_positions + idx, &dummy);
+ }
+ record_count *= join->best_positions[idx].records_read;
+ rem_tables &= ~join->best_positions[idx].table->table->map;
+ }
+ }
+
+ if (pos->sj_strategy == SJ_OPT_LOOSE_SCAN)
+ {
+ first= pos->first_loosescan_table;
+ POSITION *first_pos= join->best_positions + first;
+ POSITION loose_scan_pos; // For loose scan paths
+ double record_count= (first== join->const_tables)? 1.0:
+ join->best_positions[tablenr - 1].prefix_record_count;
+
+ table_map rem_tables= remaining_tables;
+ uint idx;
+ for (idx= first; idx <= tablenr; idx++)
+ rem_tables |= join->best_positions[idx].table->table->map;
+ /*
+ Re-run best_access_path to produce best access methods that do not use
+ join buffering
+ */
+ join->cur_sj_inner_tables= 0;
+ for (idx= first; idx <= tablenr; idx++)
+ {
+ if (join->best_positions[idx].use_join_buffer || (idx == first))
+ {
+ best_access_path(join, join->best_positions[idx].table,
+ rem_tables, idx, TRUE /* no jbuf */,
+ record_count, join->best_positions + idx,
+ &loose_scan_pos);
+ if (idx==first)
+ join->best_positions[idx]= loose_scan_pos;
+ }
+ rem_tables &= ~join->best_positions[idx].table->table->map;
+ record_count *= join->best_positions[idx].records_read;
+ }
+ first_pos->sj_strategy= SJ_OPT_LOOSE_SCAN;
+ first_pos->n_sj_tables= my_count_bits(first_pos->table->emb_sj_nest->sj_inner_tables);
+ }
+
+ if (pos->sj_strategy == SJ_OPT_DUPS_WEEDOUT)
+ {
+ /*
+ Duplicate Weedout starting at pos->first_dupsweedout_table, ending at
+ this table.
+ */
+ first= pos->first_dupsweedout_table;
+ join->best_positions[first].sj_strategy= SJ_OPT_DUPS_WEEDOUT;
+ join->best_positions[first].n_sj_tables= tablenr - first + 1;
+ }
+
+ uint i_end= first + join->best_positions[first].n_sj_tables;
+ for (uint i= first; i < i_end; i++)
+ {
+ if (i != first)
+ join->best_positions[i].sj_strategy= SJ_OPT_NONE;
+ handled_tabs |= join->best_positions[i].table->table->map;
+ }
+
+ if (tablenr != first)
+ pos->sj_strategy= SJ_OPT_NONE;
+ remaining_tables |= s->table->map;
+ //s->sj_strategy= pos->sj_strategy;
+ join->join_tab[first].sj_strategy= join->best_positions[first].sj_strategy;
+ }
+}
+
+/*
+ Setup semi-join materialization strategy for one semi-join nest
+
+ SYNOPSIS
+
+ setup_sj_materialization()
+ tab The first tab in the semi-join
+
+ DESCRIPTION
+ Setup execution structures for one semi-join materialization nest:
+ - Create the materialization temporary table
+ - If we're going to do index lookups
+ create TABLE_REF structure to make the lookus
+ - else (if we're going to do a full scan of the temptable)
+ create Copy_field structures to do copying.
+
+ RETURN
+ FALSE Ok
+ TRUE Error
+*/
+
+bool setup_sj_materialization(JOIN_TAB *tab)
+{
+ uint i;
+ DBUG_ENTER("setup_sj_materialization");
+ TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
+ SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
+ THD *thd= tab->join->thd;
+ /* First the calls come to the materialization function */
+ List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
+
+ /*
+ Set up the table to write to, do as select_union::create_result_table does
+ */
+ sjm->sjm_table_param.init();
+ sjm->sjm_table_param.field_count= item_list.elements;
+ sjm->sjm_table_param.bit_fields_as_long= TRUE;
+ List_iterator<Item> it(item_list);
+ Item *right_expr;
+ while((right_expr= it++))
+ sjm->sjm_table_cols.push_back(right_expr);
+
+ if (!(sjm->table= create_tmp_table(thd, &sjm->sjm_table_param,
+ sjm->sjm_table_cols, (ORDER*) 0,
+ TRUE /* distinct */,
+ 1, /*save_sum_fields*/
+ thd->options | TMP_TABLE_ALL_COLUMNS,
+ HA_POS_ERROR /*rows_limit */,
+ (char*)"sj-materialize")))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ sjm->table->file->extra(HA_EXTRA_WRITE_CACHE);
+ sjm->table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ tab->join->sj_tmp_tables.push_back(sjm->table);
+ tab->join->sjm_info_list.push_back(sjm);
+
+ sjm->materialized= FALSE;
+ if (!sjm->is_sj_scan)
+ {
+ KEY *tmp_key; /* The only index on the temporary table. */
+ uint tmp_key_parts; /* Number of keyparts in tmp_key. */
+ tmp_key= sjm->table->key_info;
+ tmp_key_parts= tmp_key->key_parts;
+
+ /*
+ Create/initialize everything we will need to index lookups into the
+ temptable.
+ */
+ TABLE_REF *tab_ref;
+ if (!(tab_ref= (TABLE_REF*) thd->alloc(sizeof(TABLE_REF))))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ tab_ref->key= 0; /* The only temp table index. */
+ tab_ref->key_length= tmp_key->key_length;
+ if (!(tab_ref->key_buff=
+ (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
+ !(tab_ref->key_copy=
+ (store_key**) thd->alloc((sizeof(store_key*) *
+ (tmp_key_parts + 1)))) ||
+ !(tab_ref->items=
+ (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
+ tab_ref->key_buff2=tab_ref->key_buff+ALIGN_SIZE(tmp_key->key_length);
+ tab_ref->key_err=1;
+ tab_ref->null_rejecting= 1;
+ tab_ref->disable_cache= FALSE;
+
+ KEY_PART_INFO *cur_key_part= tmp_key->key_part;
+ store_key **ref_key= tab_ref->key_copy;
+ uchar *cur_ref_buff= tab_ref->key_buff;
+
+ for (i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
+ {
+ tab_ref->items[i]= emb_sj_nest->sj_subq_pred->left_expr->element_index(i);
+ int null_count= test(cur_key_part->field->real_maybe_null());
+ *ref_key= new store_key_item(thd, cur_key_part->field,
+ /* TODO:
+ the NULL byte is taken into account in
+ cur_key_part->store_length, so instead of
+ cur_ref_buff + test(maybe_null), we could
+ use that information instead.
+ */
+ cur_ref_buff + null_count,
+ null_count ? tab_ref->key_buff : 0,
+ cur_key_part->length, tab_ref->items[i],
+ FALSE);
+ cur_ref_buff+= cur_key_part->store_length;
+ }
+ *ref_key= NULL; /* End marker. */
+ tab_ref->key_err= 1;
+ tab_ref->key_parts= tmp_key_parts;
+ sjm->tab_ref= tab_ref;
+
+ /*
+ Remove the injected semi-join IN-equalities from join_tab conds. This
+ needs to be done because the IN-equalities refer to columns of
+ sj-inner tables which are not available after the materialization
+ has been finished.
+ */
+ for (i= 0; i < sjm->tables; i++)
+ {
+ remove_sj_conds(&tab[i].select_cond);
+ if (tab[i].select)
+ remove_sj_conds(&tab[i].select->cond);
+ }
+ if (!(sjm->in_equality= create_subq_in_equalities(thd, sjm,
+ emb_sj_nest->sj_subq_pred)))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ }
+ else
+ {
+ /*
+ We'll be doing full scan of the temptable.
+ Setup copying of temptable columns back to the record buffers
+ for their source tables. We need this because IN-equalities
+ refer to the original tables.
+
+ EXAMPLE
+
+ Consider the query:
+ SELECT * FROM ot WHERE ot.col1 IN (SELECT it.col2 FROM it)
+
+ Suppose it's executed with SJ-Materialization-scan. We choose to do scan
+ if we can't do the lookup, i.e. the join order is (it, ot). The plan
+ would look as follows:
+
+ table access method condition
+ it materialize+scan -
+ ot (whatever) ot1.col1=it.col2 (C2)
+
+ The condition C2 refers to current row of table it. The problem is
+ that by the time we evaluate C2, we would have finished with scanning
+ it itself and will be scanning the temptable.
+
+ At the moment, our solution is to copy back: when we get the next
+ temptable record, we copy its columns to their corresponding columns
+ in the record buffers for the source tables.
+ */
+ sjm->copy_field= new Copy_field[sjm->sjm_table_cols.elements];
+ it.rewind();
+ for (uint i=0; i < sjm->sjm_table_cols.elements; i++)
+ {
+ bool dummy;
+ Item_equal *item_eq;
+ Item *item= (it++)->real_item();
+ DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
+ Field *copy_to= ((Item_field*)item)->field;
+ /*
+ Tricks with Item_equal are due to the following: suppose we have a
+ query:
+
+ ... WHERE cond(ot.col) AND ot.col IN (SELECT it2.col FROM it1,it2
+ WHERE it1.col= it2.col)
+ then equality propagation will create an
+
+ Item_equal(it1.col, it2.col, ot.col)
+
+ then substitute_for_best_equal_field() will change the conditions
+ according to the join order:
+
+ it1
+ it2 it1.col=it2.col
+ ot cond(it1.col)
+
+ although we've originally had "SELECT it2.col", conditions attached
+ to subsequent outer tables will refer to it1.col, so SJM-Scan will
+ need to unpack data to there.
+ That is, if an element from subquery's select list participates in
+ equality propagation, then we need to unpack it to the first
+ element equality propagation member that refers to table that is
+ within the subquery.
+ */
+ item_eq= find_item_equal(tab->join->cond_equal, copy_to, &dummy);
+
+ if (item_eq)
+ {
+ List_iterator<Item_field> it(item_eq->fields);
+ Item_field *item;
+ while ((item= it++))
+ {
+ if (!(item->used_tables() & ~emb_sj_nest->sj_inner_tables))
+ {
+ copy_to= item->field;
+ break;
+ }
+ }
+ }
+ sjm->copy_field[i].set(copy_to, sjm->table->field[i], FALSE);
+ /* The write_set for source tables must be set up to allow the copying */
+ bitmap_set_bit(copy_to->table->write_set, copy_to->field_index);
+ }
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+
+/*
+ Create subquery IN-equalities assuming use of materialization strategy
+
+ SYNOPSIS
+ create_subq_in_equalities()
+ thd Thread handle
+ sjm Semi-join materialization structure
+ subq_pred The subquery predicate
+
+ DESCRIPTION
+ Create subquery IN-equality predicates. That is, for a subquery
+
+ (oe1, oe2, ...) IN (SELECT ie1, ie2, ... FROM ...)
+
+ create "oe1=ie1 AND ie1=ie2 AND ..." expression, such that ie1, ie2, ..
+ refer to the columns of the table that's used to materialize the
+ subquery.
+
+ RETURN
+ Created condition
+*/
+
+static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm,
+ Item_in_subselect *subq_pred)
+{
+ Item *res= NULL;
+ if (subq_pred->left_expr->cols() == 1)
+ {
+ if (!(res= new Item_func_eq(subq_pred->left_expr,
+ new Item_field(sjm->table->field[0]))))
+ return NULL; /* purecov: inspected */
+ }
+ else
+ {
+ Item *conj;
+ for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
+ {
+ if (!(conj= new Item_func_eq(subq_pred->left_expr->element_index(i),
+ new Item_field(sjm->table->field[i]))) ||
+ !(res= and_items(res, conj)))
+ return NULL; /* purecov: inspected */
+ }
+ }
+ if (res->fix_fields(thd, &res))
+ return NULL; /* purecov: inspected */
+ return res;
+}
+
+
+
+
+static void remove_sj_conds(Item **tree)
+{
+ if (*tree)
+ {
+ if (is_cond_sj_in_equality(*tree))
+ {
+ *tree= NULL;
+ return;
+ }
+ else if ((*tree)->type() == Item::COND_ITEM)
+ {
+ Item *item;
+ List_iterator<Item> li(*(((Item_cond*)*tree)->argument_list()));
+ while ((item= li++))
+ {
+ if (is_cond_sj_in_equality(item))
+ li.replace(new Item_int(1));
+ }
+ }
+ }
+}
+
+/* Check if given Item was injected by semi-join equality */
+static bool is_cond_sj_in_equality(Item *item)
+{
+ if (item->type() == Item::FUNC_ITEM &&
+ ((Item_func*)item)->functype()== Item_func::EQ_FUNC)
+ {
+ Item_func_eq *item_eq= (Item_func_eq*)item;
+ return test(item_eq->in_equality_no != UINT_MAX);
+ }
+ return FALSE;
+}
+
+
+/*
+ Create a temporary table to weed out duplicate rowid combinations
+
+ SYNOPSIS
+
+ create_duplicate_weedout_tmp_table()
+ thd Thread handle
+ uniq_tuple_length_arg Length of the table's column
+ sjtbl Update sjtbl->[start_]recinfo values which
+ will be needed if we'll need to convert the
+ created temptable from HEAP to MyISAM/Maria.
+
+ DESCRIPTION
+ Create a temporary table to weed out duplicate rowid combinations. The
+ table has a single column that is a concatenation of all rowids in the
+ combination.
+
+ Depending on the needed length, there are two cases:
+
+ 1. When the length of the column < max_key_length:
+
+ CREATE TABLE tmp (col VARBINARY(n) NOT NULL, UNIQUE KEY(col));
+
+ 2. Otherwise (not a valid SQL syntax but internally supported):
+
+ CREATE TABLE tmp (col VARBINARY NOT NULL, UNIQUE CONSTRAINT(col));
+
+ The code in this function was produced by extraction of relevant parts
+ from create_tmp_table().
+
+ RETURN
+ created table
+ NULL on error
+*/
+
+TABLE *create_duplicate_weedout_tmp_table(THD *thd,
+ uint uniq_tuple_length_arg,
+ SJ_TMP_TABLE *sjtbl)
+{
+ MEM_ROOT *mem_root_save, own_root;
+ TABLE *table;
+ TABLE_SHARE *share;
+ uint temp_pool_slot=MY_BIT_NONE;
+ char *tmpname,path[FN_REFLEN];
+ Field **reg_field;
+ KEY_PART_INFO *key_part_info;
+ KEY *keyinfo;
+ uchar *group_buff;
+ uchar *bitmaps;
+ uint *blob_field;
+ ENGINE_COLUMNDEF *recinfo, *start_recinfo;
+ bool using_unique_constraint=FALSE;
+ bool use_packed_rows= FALSE;
+ Field *field, *key_field;
+ uint blob_count, null_pack_length, null_count;
+ uchar *null_flags;
+ uchar *pos;
+ DBUG_ENTER("create_duplicate_weedout_tmp_table");
+ DBUG_ASSERT(!sjtbl->is_degenerate);
+ /*
+ STEP 1: Get temporary table name
+ */
+ statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
+ if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
+ temp_pool_slot = bitmap_lock_set_next(&temp_pool);
+
+ if (temp_pool_slot != MY_BIT_NONE) // we got a slot
+ sprintf(path, "%s_%lx_%i", tmp_file_prefix,
+ current_pid, temp_pool_slot);
+ else
+ {
+ /* if we run out of slots or we are not using tempool */
+ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
+ thd->thread_id, thd->tmp_table++);
+ }
+ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+
+ /* STEP 2: Figure if we'll be using a key or blob+constraint */
+ if (uniq_tuple_length_arg >= CONVERT_IF_BIGGER_TO_BLOB)
+ using_unique_constraint= TRUE;
+
+ /* STEP 3: Allocate memory for temptable description */
+ init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
+ if (!multi_alloc_root(&own_root,
+ &table, sizeof(*table),
+ &share, sizeof(*share),
+ &reg_field, sizeof(Field*) * (1+1),
+ &blob_field, sizeof(uint)*2,
+ &keyinfo, sizeof(*keyinfo),
+ &key_part_info, sizeof(*key_part_info) * 2,
+ &start_recinfo,
+ sizeof(*recinfo)*(1*2+4),
+ &tmpname, (uint) strlen(path)+1,
+ &group_buff, (!using_unique_constraint ?
+ uniq_tuple_length_arg : 0),
+ &bitmaps, bitmap_buffer_size(1)*3,
+ NullS))
+ {
+ if (temp_pool_slot != MY_BIT_NONE)
+ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
+ DBUG_RETURN(NULL);
+ }
+ strmov(tmpname,path);
+
+
+ /* STEP 4: Create TABLE description */
+ bzero((char*) table,sizeof(*table));
+ bzero((char*) reg_field,sizeof(Field*)*2);
+
+ table->mem_root= own_root;
+ mem_root_save= thd->mem_root;
+ thd->mem_root= &table->mem_root;
+
+ table->field=reg_field;
+ table->alias.set("weedout-tmp", sizeof("weedout-tmp")-1,
+ table_alias_charset);
+ table->reginfo.lock_type=TL_WRITE; /* Will be updated */
+ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
+ table->map=1;
+ table->temp_pool_slot = temp_pool_slot;
+ table->copy_blobs= 1;
+ table->in_use= thd;
+ table->quick_keys.init();
+ table->covering_keys.init();
+ table->keys_in_use_for_query.init();
+
+ table->s= share;
+ init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
+ share->blob_field= blob_field;
+ share->blob_ptr_size= portable_sizeof_char_ptr;
+ share->db_low_byte_first=1; // True for HEAP and MyISAM
+ share->table_charset= NULL;
+ share->primary_key= MAX_KEY; // Indicate no primary key
+ share->keys_for_keyread.init();
+ share->keys_in_use.init();
+
+ blob_count= 0;
+
+ /* Create the field */
+ {
+ /*
+ For the sake of uniformity, always use Field_varstring (altough we could
+ use Field_string for shorter keys)
+ */
+ field= new Field_varstring(uniq_tuple_length_arg, FALSE, "rowids", share,
+ &my_charset_bin);
+ if (!field)
+ DBUG_RETURN(0);
+ field->table= table;
+ field->key_start.init(0);
+ field->part_of_key.init(0);
+ field->part_of_sortkey.init(0);
+ field->unireg_check= Field::NONE;
+ field->flags= (NOT_NULL_FLAG | BINARY_FLAG | NO_DEFAULT_VALUE_FLAG);
+ field->reset_fields();
+ field->init(table);
+ field->orig_table= NULL;
+
+ field->field_index= 0;
+
+ *(reg_field++)= field;
+ *blob_field= 0;
+ *reg_field= 0;
+
+ share->fields= 1;
+ share->blob_fields= 0;
+ }
+
+ uint reclength= field->pack_length();
+ if (using_unique_constraint)
+ {
+ share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
+ table->file= get_new_handler(share, &table->mem_root,
+ share->db_type());
+ DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length());
+ }
+ else
+ {
+ share->db_plugin= ha_lock_engine(0, heap_hton);
+ table->file= get_new_handler(share, &table->mem_root,
+ share->db_type());
+ }
+ if (!table->file)
+ goto err;
+
+ null_count=1;
+
+ null_pack_length= 1;
+ reclength += null_pack_length;
+
+ share->reclength= reclength;
+ {
+ uint alloc_length=ALIGN_SIZE(share->reclength + MI_UNIQUE_HASH_LENGTH+1);
+ share->rec_buff_length= alloc_length;
+ if (!(table->record[0]= (uchar*)
+ alloc_root(&table->mem_root, alloc_length*3)))
+ goto err;
+ table->record[1]= table->record[0]+alloc_length;
+ share->default_values= table->record[1]+alloc_length;
+ }
+ setup_tmp_table_column_bitmaps(table, bitmaps);
+
+ recinfo= start_recinfo;
+ null_flags=(uchar*) table->record[0];
+ pos=table->record[0]+ null_pack_length;
+ if (null_pack_length)
+ {
+ bzero((uchar*) recinfo,sizeof(*recinfo));
+ recinfo->type=FIELD_NORMAL;
+ recinfo->length=null_pack_length;
+ recinfo++;
+ bfill(null_flags,null_pack_length,255); // Set null fields
+
+ table->null_flags= (uchar*) table->record[0];
+ share->null_fields= null_count;
+ share->null_bytes= null_pack_length;
+ }
+ null_count=1;
+
+ {
+ //Field *field= *reg_field;
+ uint length;
+ bzero((uchar*) recinfo,sizeof(*recinfo));
+ field->move_field(pos,(uchar*) 0,0);
+
+ field->reset();
+ /*
+ Test if there is a default field value. The test for ->ptr is to skip
+ 'offset' fields generated by initalize_tables
+ */
+ // Initialize the table field:
+ bzero(field->ptr, field->pack_length());
+
+ length=field->pack_length();
+ pos+= length;
+
+ /* Make entry for create table */
+ recinfo->length=length;
+ if (field->flags & BLOB_FLAG)
+ recinfo->type= FIELD_BLOB;
+ else if (use_packed_rows &&
+ field->real_type() == MYSQL_TYPE_STRING &&
+ length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
+ recinfo->type=FIELD_SKIP_ENDSPACE;
+ else
+ recinfo->type=FIELD_NORMAL;
+
+ field->set_table_name(&table->alias);
+ }
+
+ //param->recinfo=recinfo;
+ //store_record(table,s->default_values); // Make empty default record
+
+ if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+ min(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+ set_if_bigger(share->max_rows,1); // For dummy start options
+
+
+ //// keyinfo= param->keyinfo;
+ if (TRUE)
+ {
+ DBUG_PRINT("info",("Creating group key in temporary table"));
+ share->keys=1;
+ share->uniques= test(using_unique_constraint);
+ table->key_info=keyinfo;
+ keyinfo->key_part=key_part_info;
+ keyinfo->flags=HA_NOSAME;
+ keyinfo->usable_key_parts= keyinfo->key_parts= 1;
+ keyinfo->key_length=0;
+ keyinfo->rec_per_key=0;
+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
+ keyinfo->name= (char*) "weedout_key";
+ {
+ key_part_info->null_bit=0;
+ key_part_info->field= field;
+ key_part_info->offset= field->offset(table->record[0]);
+ key_part_info->length= (uint16) field->key_length();
+ key_part_info->type= (uint8) field->key_type();
+ key_part_info->key_type = FIELDFLAG_BINARY;
+ if (!using_unique_constraint)
+ {
+ if (!(key_field= field->new_key_field(thd->mem_root, table,
+ group_buff,
+ field->null_ptr,
+ field->null_bit)))
+ goto err;
+ key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; //todo need this?
+ }
+ keyinfo->key_length+= key_part_info->length;
+ }
+ }
+
+ if (thd->is_fatal_error) // If end of memory
+ goto err;
+ share->db_record_offset= 1;
+ if (share->db_type() == TMP_ENGINE_HTON)
+ {
+ recinfo++;
+ if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
+ goto err;
+ }
+ sjtbl->start_recinfo= start_recinfo;
+ sjtbl->recinfo= recinfo;
+ if (open_tmp_table(table))
+ goto err;
+
+ thd->mem_root= mem_root_save;
+ DBUG_RETURN(table);
+
+err:
+ thd->mem_root= mem_root_save;
+ free_tmp_table(thd,table); /* purecov: inspected */
+ if (temp_pool_slot != MY_BIT_NONE)
+ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
+ DBUG_RETURN(NULL); /* purecov: inspected */
+}
+
+
+/*
+ SemiJoinDuplicateElimination: Reset the temporary table
+*/
+
+int do_sj_reset(SJ_TMP_TABLE *sj_tbl)
+{
+ DBUG_ENTER("do_sj_reset");
+ if (sj_tbl->tmp_table)
+ {
+ int rc= sj_tbl->tmp_table->file->ha_delete_all_rows();
+ DBUG_RETURN(rc);
+ }
+ sj_tbl->have_degenerate_row= FALSE;
+ DBUG_RETURN(0);
+}
+
+/*
+ SemiJoinDuplicateElimination: Weed out duplicate row combinations
+
+ SYNPOSIS
+ do_sj_dups_weedout()
+ thd Thread handle
+ sjtbl Duplicate weedout table
+
+ DESCRIPTION
+ Try storing current record combination of outer tables (i.e. their
+ rowids) in the temporary table. This records the fact that we've seen
+ this record combination and also tells us if we've seen it before.
+
+ RETURN
+ -1 Error
+ 1 The row combination is a duplicate (discard it)
+ 0 The row combination is not a duplicate (continue)
+*/
+
+int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
+{
+ int error;
+ SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
+ SJ_TMP_TABLE::TAB *tab_end= sjtbl->tabs_end;
+ uchar *ptr;
+ uchar *nulls_ptr;
+
+ DBUG_ENTER("do_sj_dups_weedout");
+
+ if (sjtbl->is_degenerate)
+ {
+ if (sjtbl->have_degenerate_row)
+ DBUG_RETURN(1);
+
+ sjtbl->have_degenerate_row= TRUE;
+ DBUG_RETURN(0);
+ }
+
+ ptr= sjtbl->tmp_table->record[0] + 1;
+ nulls_ptr= ptr;
+
+ /* Put the the rowids tuple into table->record[0]: */
+
+ // 1. Store the length
+ if (((Field_varstring*)(sjtbl->tmp_table->field[0]))->length_bytes == 1)
+ {
+ *ptr= (uchar)(sjtbl->rowid_len + sjtbl->null_bytes);
+ ptr++;
+ }
+ else
+ {
+ int2store(ptr, sjtbl->rowid_len + sjtbl->null_bytes);
+ ptr += 2;
+ }
+
+ // 2. Zero the null bytes
+ if (sjtbl->null_bytes)
+ {
+ bzero(ptr, sjtbl->null_bytes);
+ ptr += sjtbl->null_bytes;
+ }
+
+ // 3. Put the rowids
+ for (uint i=0; tab != tab_end; tab++, i++)
+ {
+ handler *h= tab->join_tab->table->file;
+ if (tab->join_tab->table->maybe_null && tab->join_tab->table->null_row)
+ {
+ /* It's a NULL-complemented row */
+ *(nulls_ptr + tab->null_byte) |= tab->null_bit;
+ bzero(ptr + tab->rowid_offset, h->ref_length);
+ }
+ else
+ {
+ /* Copy the rowid value */
+ memcpy(ptr + tab->rowid_offset, h->ref, h->ref_length);
+ }
+ }
+
+ error= sjtbl->tmp_table->file->ha_write_row(sjtbl->tmp_table->record[0]);
+ if (error)
+ {
+ /* create_internal_tmp_table_from_heap will generate error if needed */
+ if (!sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP))
+ DBUG_RETURN(1); /* Duplicate */
+ if (create_internal_tmp_table_from_heap(thd, sjtbl->tmp_table,
+ sjtbl->start_recinfo,
+ &sjtbl->recinfo, error, 1))
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Setup the strategies to eliminate semi-join duplicates.
+
+ SYNOPSIS
+ setup_semijoin_dups_elimination()
+ join Join to process
+ options Join options (needed to see if join buffering will be
+ used or not)
+ no_jbuf_after Another bit of information re where join buffering will
+ be used.
+
+ DESCRIPTION
+ Setup the strategies to eliminate semi-join duplicates. ATM there are 4
+ strategies:
+
+ 1. DuplicateWeedout (use of temptable to remove duplicates based on rowids
+ of row combinations)
+ 2. FirstMatch (pick only the 1st matching row combination of inner tables)
+ 3. LooseScan (scanning the sj-inner table in a way that groups duplicates
+ together and picking the 1st one)
+ 4. SJ-Materialization.
+
+ The join order has "duplicate-generating ranges", and every range is
+ served by one strategy or a combination of FirstMatch with with some
+ other strategy.
+
+ "Duplicate-generating range" is defined as a range within the join order
+ that contains all of the inner tables of a semi-join. All ranges must be
+ disjoint, if tables of several semi-joins are interleaved, then the ranges
+ are joined together, which is equivalent to converting
+ SELECT ... WHERE oe1 IN (SELECT ie1 ...) AND oe2 IN (SELECT ie2 )
+ to
+ SELECT ... WHERE (oe1, oe2) IN (SELECT ie1, ie2 ... ...)
+ .
+
+ Applicability conditions are as follows:
+
+ DuplicateWeedout strategy
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ (ot|nt)* [ it ((it|ot|nt)* (it|ot))] (nt)*
+ +------+ +=========================+ +---+
+ (1) (2) (3)
+
+ (1) - Prefix of OuterTables (those that participate in
+ IN-equality and/or are correlated with subquery) and outer
+ Non-correlated tables.
+ (2) - The handled range. The range starts with the first sj-inner
+ table, and covers all sj-inner and outer tables
+ Within the range, Inner, Outer, outer non-correlated tables
+ may follow in any order.
+ (3) - The suffix of outer non-correlated tables.
+
+ FirstMatch strategy
+ ~~~~~~~~~~~~~~~~~~~
+
+ (ot|nt)* [ it ((it|nt)* it) ] (nt)*
+ +------+ +==================+ +---+
+ (1) (2) (3)
+
+ (1) - Prefix of outer and non-correlated tables
+ (2) - The handled range, which may contain only inner and
+ non-correlated tables.
+ (3) - The suffix of outer non-correlated tables.
+
+ LooseScan strategy
+ ~~~~~~~~~~~~~~~~~~
+
+ (ot|ct|nt) [ loosescan_tbl (ot|nt|it)* it ] (ot|nt)*
+ +--------+ +===========+ +=============+ +------+
+ (1) (2) (3) (4)
+
+ (1) - Prefix that may contain any outer tables. The prefix must contain
+ all the non-trivially correlated outer tables. (non-trivially means
+ that the correlation is not just through the IN-equality).
+
+ (2) - Inner table for which the LooseScan scan is performed.
+
+ (3) - The remainder of the duplicate-generating range. It is served by
+ application of FirstMatch strategy, with the exception that
+ outer IN-correlated tables are considered to be non-correlated.
+
+ (4) - THe suffix of outer and outer non-correlated tables.
+
+
+ The choice between the strategies is made by the join optimizer (see
+ advance_sj_state() and fix_semijoin_strategies_for_picked_join_order()).
+ This function sets up all fields/structures/etc needed for execution except
+ for setup/initialization of semi-join materialization which is done in
+ setup_sj_materialization() (todo: can't we move that to here also?)
+
+ RETURN
+ FALSE OK
+ TRUE Out of memory error
+*/
+
+int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
+ uint no_jbuf_after)
+{
+ uint i;
+ THD *thd= join->thd;
+ DBUG_ENTER("setup_semijoin_dups_elimination");
+
+ for (i= join->const_tables ; i < join->tables; )
+ {
+ JOIN_TAB *tab=join->join_tab + i;
+ POSITION *pos= join->best_positions + i;
+ uint keylen, keyno;
+ switch (pos->sj_strategy) {
+ case SJ_OPT_MATERIALIZE:
+ case SJ_OPT_MATERIALIZE_SCAN:
+ /* Do nothing */
+ i+= pos->n_sj_tables;
+ break;
+ case SJ_OPT_LOOSE_SCAN:
+ {
+ /* We jump from the last table to the first one */
+ tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
+
+ /* Calculate key length */
+ keylen= 0;
+ keyno= pos->loosescan_key;
+ for (uint kp=0; kp < pos->loosescan_parts; kp++)
+ keylen += tab->table->key_info[keyno].key_part[kp].store_length;
+
+ tab->loosescan_key_len= keylen;
+ if (pos->n_sj_tables > 1)
+ tab[pos->n_sj_tables - 1].do_firstmatch= tab;
+ i+= pos->n_sj_tables;
+ break;
+ }
+ case SJ_OPT_DUPS_WEEDOUT:
+ {
+ /*
+ Check for join buffering. If there is one, move the first table
+ forwards, but do not destroy other duplicate elimination methods.
+ */
+ uint first_table= i;
+ uint join_cache_level= join->thd->variables.join_cache_level;
+ for (uint j= i; j < i + pos->n_sj_tables; j++)
+ {
+ /*
+ When we'll properly take join buffering into account during
+ join optimization, the below check should be changed to
+ "if (join->best_positions[j].use_join_buffer &&
+ j <= no_jbuf_after)".
+ For now, use a rough criteria:
+ */
+ JOIN_TAB *js_tab=join->join_tab + j;
+ 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 ||
+ tab->type == JT_EQ_REF))))
+ {
+ /* Looks like we'll be using join buffer */
+ first_table= join->const_tables;
+ break;
+ }
+ }
+
+ SJ_TMP_TABLE::TAB sjtabs[MAX_TABLES];
+ SJ_TMP_TABLE::TAB *last_tab= sjtabs;
+ uint jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
+ uint jt_null_bits= 0; // # null bits in tuple bytes
+ /*
+ Walk through the range and remember
+ - tables that need their rowids to be put into temptable
+ - the last outer table
+ */
+ for (JOIN_TAB *j=join->join_tab + first_table;
+ j < join->join_tab + i + pos->n_sj_tables; j++)
+ {
+ if (sj_table_is_included(join, j))
+ {
+ last_tab->join_tab= j;
+ last_tab->rowid_offset= jt_rowid_offset;
+ jt_rowid_offset += j->table->file->ref_length;
+ if (j->table->maybe_null)
+ {
+ last_tab->null_byte= jt_null_bits / 8;
+ last_tab->null_bit= jt_null_bits++;
+ }
+ last_tab++;
+ j->table->prepare_for_position();
+ j->keep_current_rowid= TRUE;
+ }
+ }
+
+ SJ_TMP_TABLE *sjtbl;
+ if (jt_rowid_offset) /* Temptable has at least one rowid */
+ {
+ uint tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
+ if (!(sjtbl= (SJ_TMP_TABLE*)thd->alloc(sizeof(SJ_TMP_TABLE))) ||
+ !(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) thd->alloc(tabs_size)))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ memcpy(sjtbl->tabs, sjtabs, tabs_size);
+ sjtbl->is_degenerate= FALSE;
+ sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
+ sjtbl->rowid_len= jt_rowid_offset;
+ sjtbl->null_bits= jt_null_bits;
+ sjtbl->null_bytes= (jt_null_bits + 7)/8;
+ sjtbl->tmp_table=
+ create_duplicate_weedout_tmp_table(thd,
+ sjtbl->rowid_len +
+ sjtbl->null_bytes,
+ sjtbl);
+ join->sj_tmp_tables.push_back(sjtbl->tmp_table);
+ }
+ else
+ {
+ /*
+ This is a special case where the entire subquery predicate does
+ not depend on anything at all, ie this is
+ WHERE const IN (uncorrelated select)
+ */
+ if (!(sjtbl= (SJ_TMP_TABLE*)thd->alloc(sizeof(SJ_TMP_TABLE))))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ sjtbl->tmp_table= NULL;
+ sjtbl->is_degenerate= TRUE;
+ sjtbl->have_degenerate_row= FALSE;
+ }
+ join->join_tab[first_table].flush_weedout_table= sjtbl;
+ join->join_tab[i + pos->n_sj_tables - 1].check_weed_out_table= sjtbl;
+
+ i+= pos->n_sj_tables;
+ break;
+ }
+ case SJ_OPT_FIRST_MATCH:
+ {
+ JOIN_TAB *j, *jump_to= tab-1;
+ for (j= tab; j != tab + pos->n_sj_tables; j++)
+ {
+ /*
+ NOTE: this loop probably doesn't do the right thing for the case
+ where FirstMatch's duplicate-generating range is interleaved with
+ "unrelated" tables (as specified in WL#3750, section 2.2).
+ */
+ if (!j->emb_sj_nest)
+ jump_to= tab;
+ else
+ {
+ j->first_sj_inner_tab= tab;
+ j->last_sj_inner_tab= tab + pos->n_sj_tables - 1;
+ }
+ }
+ j[-1].do_firstmatch= jump_to;
+ i+= pos->n_sj_tables;
+ break;
+ }
+ case SJ_OPT_NONE:
+ i++;
+ break;
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ Destroy all temporary tables created by NL-semijoin runtime
+*/
+
+void destroy_sj_tmp_tables(JOIN *join)
+{
+ List_iterator<TABLE> it(join->sj_tmp_tables);
+ TABLE *table;
+ while ((table= it++))
+ {
+ /*
+ SJ-Materialization tables are initialized for either sequential reading
+ or index lookup, DuplicateWeedout tables are not initialized for read
+ (we only write to them), so need to call ha_index_or_rnd_end.
+ */
+ table->file->ha_index_or_rnd_end();
+ free_tmp_table(join->thd, table);
+ }
+ join->sj_tmp_tables.empty();
+ join->sjm_info_list.empty();
+}
+
+
+/*
+ Remove all records from all temp tables used by NL-semijoin runtime
+
+ SYNOPSIS
+ clear_sj_tmp_tables()
+ join The join to remove tables for
+
+ DESCRIPTION
+ Remove all records from all temp tables used by NL-semijoin runtime. This
+ must be done before every join re-execution.
+*/
+
+int clear_sj_tmp_tables(JOIN *join)
+{
+ int res;
+ List_iterator<TABLE> it(join->sj_tmp_tables);
+ TABLE *table;
+ while ((table= it++))
+ {
+ if ((res= table->file->ha_delete_all_rows()))
+ return res; /* purecov: inspected */
+ }
+
+ SJ_MATERIALIZATION_INFO *sjm;
+ List_iterator<SJ_MATERIALIZATION_INFO> it2(join->sjm_info_list);
+ while ((sjm= it2++))
+ {
+ sjm->materialized= FALSE;
+ }
+ return 0;
+}
+
+
+/*
+ Check if the table's rowid is included in the temptable
+
+ SYNOPSIS
+ sj_table_is_included()
+ join The join
+ join_tab The table to be checked
+
+ DESCRIPTION
+ SemiJoinDuplicateElimination: check the table's rowid should be included
+ in the temptable. This is so if
+
+ 1. The table is not embedded within some semi-join nest
+ 2. The has been pulled out of a semi-join nest, or
+
+ 3. The table is functionally dependent on some previous table
+
+ [4. This is also true for constant tables that can't be
+ NULL-complemented but this function is not called for such tables]
+
+ RETURN
+ TRUE - Include table's rowid
+ FALSE - Don't
+*/
+
+static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab)
+{
+ if (join_tab->emb_sj_nest)
+ return FALSE;
+
+ /* Check if this table is functionally dependent on the tables that
+ are within the same outer join nest
+ */
+ TABLE_LIST *embedding= join_tab->table->pos_in_table_list->embedding;
+ if (join_tab->type == JT_EQ_REF)
+ {
+ table_map depends_on= 0;
+ uint idx;
+
+ for (uint kp= 0; kp < join_tab->ref.key_parts; kp++)
+ depends_on |= join_tab->ref.items[kp]->used_tables();
+
+ Table_map_iterator it(depends_on & ~PSEUDO_TABLE_BITS);
+ while ((idx= it.next_bit())!=Table_map_iterator::BITMAP_END)
+ {
+ JOIN_TAB *ref_tab= join->map2table[idx];
+ if (embedding != ref_tab->table->pos_in_table_list->embedding)
+ return TRUE;
+ }
+ /* Ok, functionally dependent */
+ return FALSE;
+ }
+ /* Not functionally dependent => need to include*/
+ return TRUE;
+}
+
+
+/*
+ Index lookup-based subquery: save some flags for EXPLAIN output
+
+ SYNOPSIS
+ save_index_subquery_explain_info()
+ join_tab Subquery's join tab (there is only one as index lookup is
+ only used for subqueries that are single-table SELECTs)
+ where Subquery's WHERE clause
+
+ DESCRIPTION
+ For index lookup-based subquery (i.e. one executed with
+ subselect_uniquesubquery_engine or subselect_indexsubquery_engine),
+ check its EXPLAIN output row should contain
+ "Using index" (TAB_INFO_FULL_SCAN_ON_NULL)
+ "Using Where" (TAB_INFO_USING_WHERE)
+ "Full scan on NULL key" (TAB_INFO_FULL_SCAN_ON_NULL)
+ and set appropriate flags in join_tab->packed_info.
+*/
+
+static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
+{
+ join_tab->packed_info= TAB_INFO_HAVE_VALUE;
+ if (join_tab->table->covering_keys.is_set(join_tab->ref.key))
+ join_tab->packed_info |= TAB_INFO_USING_INDEX;
+ if (where)
+ join_tab->packed_info |= TAB_INFO_USING_WHERE;
+ for (uint i = 0; i < join_tab->ref.key_parts; i++)
+ {
+ if (join_tab->ref.cond_guards[i])
+ {
+ join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
+ break;
+ }
+ }
+}
+
+
+/*
+ Check if the join can be rewritten to [unique_]indexsubquery_engine
+
+ DESCRIPTION
+ Check if the join can be changed into [unique_]indexsubquery_engine.
+
+ The check is done after join optimization, the idea is that if the join
+ has only one table and uses a [eq_]ref access generated from subselect's
+ IN-equality then we replace it with a subselect_indexsubquery_engine or a
+ subselect_uniquesubquery_engine.
+
+ RETURN
+ 0 - Ok, rewrite done (stop join optimization and return)
+ 1 - Fatal error (stop join optimization and return)
+ -1 - No rewrite performed, continue with join optimization
+*/
+
+int rewrite_to_index_subquery_engine(JOIN *join)
+{
+ THD *thd= join->thd;
+ JOIN_TAB* join_tab=join->join_tab;
+ SELECT_LEX_UNIT *unit= join->unit;
+ DBUG_ENTER("rewrite_to_index_subquery_engine");
+ /*
+ is this simple IN subquery?
+ */
+ if (!join->group_list && !join->order &&
+ join->unit->item &&
+ join->unit->item->substype() == Item_subselect::IN_SUBS &&
+ join->tables == 1 && join->conds &&
+ !join->unit->is_union())
+ {
+ if (!join->having)
+ {
+ Item *where= join->conds;
+ if (join_tab[0].type == JT_EQ_REF &&
+ join_tab[0].ref.items[0]->name == in_left_expr_name)
+ {
+ remove_subq_pushed_predicates(join, &where);
+ save_index_subquery_explain_info(join_tab, where);
+ join_tab[0].type= JT_UNIQUE_SUBQUERY;
+ join->error= 0;
+ DBUG_RETURN(unit->item->
+ change_engine(new
+ subselect_uniquesubquery_engine(thd,
+ join_tab,
+ unit->item,
+ where)));
+ }
+ else if (join_tab[0].type == JT_REF &&
+ join_tab[0].ref.items[0]->name == in_left_expr_name)
+ {
+ remove_subq_pushed_predicates(join, &where);
+ save_index_subquery_explain_info(join_tab, where);
+ join_tab[0].type= JT_INDEX_SUBQUERY;
+ join->error= 0;
+ DBUG_RETURN(unit->item->
+ change_engine(new
+ subselect_indexsubquery_engine(thd,
+ join_tab,
+ unit->item,
+ where,
+ NULL,
+ 0)));
+ }
+ } else if (join_tab[0].type == JT_REF_OR_NULL &&
+ join_tab[0].ref.items[0]->name == in_left_expr_name &&
+ join->having->name == in_having_cond)
+ {
+ join_tab[0].type= JT_INDEX_SUBQUERY;
+ join->error= 0;
+ join->conds= remove_additional_cond(join->conds);
+ save_index_subquery_explain_info(join_tab, join->conds);
+ DBUG_RETURN(unit->item->
+ change_engine(new subselect_indexsubquery_engine(thd,
+ join_tab,
+ unit->item,
+ join->conds,
+ join->having,
+ 1)));
+ }
+ }
+
+ DBUG_RETURN(-1); /* Haven't done the rewrite */
+}
+
+
+/**
+ Remove additional condition inserted by IN/ALL/ANY transformation.
+
+ @param conds condition for processing
+
+ @return
+ new conditions
+*/
+
+static Item *remove_additional_cond(Item* conds)
+{
+ if (conds->name == in_additional_cond)
+ return 0;
+ if (conds->type() == Item::COND_ITEM)
+ {
+ Item_cond *cnd= (Item_cond*) conds;
+ List_iterator<Item> li(*(cnd->argument_list()));
+ Item *item;
+ while ((item= li++))
+ {
+ if (item->name == in_additional_cond)
+ {
+ li.remove();
+ if (cnd->argument_list()->elements == 1)
+ return cnd->argument_list()->head();
+ return conds;
+ }
+ }
+ }
+ return conds;
+}
+
+
+/*
+ Remove the predicates pushed down into the subquery
+
+ SYNOPSIS
+ remove_subq_pushed_predicates()
+ where IN Must be NULL
+ OUT The remaining WHERE condition, or NULL
+
+ DESCRIPTION
+ Given that this join will be executed using (unique|index)_subquery,
+ without "checking NULL", remove the predicates that were pushed down
+ into the subquery.
+
+ If the subquery compares scalar values, we can remove the condition that
+ was wrapped into trig_cond (it will be checked when needed by the subquery
+ engine)
+
+ If the subquery compares row values, we need to keep the wrapped
+ equalities in the WHERE clause: when the left (outer) tuple has both NULL
+ and non-NULL values, we'll do a full table scan and will rely on the
+ equalities corresponding to non-NULL parts of left tuple to filter out
+ non-matching records.
+
+ TODO: We can remove the equalities that will be guaranteed to be true by the
+ fact that subquery engine will be using index lookup. This must be done only
+ for cases where there are no conversion errors of significance, e.g. 257
+ that is searched in a byte. But this requires homogenization of the return
+ codes of all Field*::store() methods.
+*/
+
+static void remove_subq_pushed_predicates(JOIN *join, Item **where)
+{
+ if (join->conds->type() == Item::FUNC_ITEM &&
+ ((Item_func *)join->conds)->functype() == Item_func::EQ_FUNC &&
+ ((Item_func *)join->conds)->arguments()[0]->type() == Item::REF_ITEM &&
+ ((Item_func *)join->conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
+ test_if_ref (join->conds,
+ (Item_field *)((Item_func *)join->conds)->arguments()[1],
+ ((Item_func *)join->conds)->arguments()[0]))
+ {
+ *where= 0;
+ return;
+ }
+}
+
+
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
new file mode 100644
index 00000000000..47d85d5c38d
--- /dev/null
+++ b/sql/opt_subselect.h
@@ -0,0 +1,369 @@
+/* */
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+int check_and_do_in_subquery_rewrites(JOIN *join);
+bool convert_join_subqueries_to_semijoins(JOIN *join);
+int pull_out_semijoin_tables(JOIN *join);
+bool optimize_semijoin_nests(JOIN *join, table_map all_table_map);
+
+// used by Loose_scan_opt
+ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
+ table_map remaining_tables);
+
+/*
+ This is a class for considering possible loose index scan optimizations.
+ It's usage pattern is as follows:
+ best_access_path()
+ {
+ Loose_scan_opt opt;
+
+ opt.init()
+ for each index we can do ref access with
+ {
+ opt.next_ref_key();
+ for each keyuse
+ opt.add_keyuse();
+ opt.check_ref_access();
+ }
+
+ if (some criteria for range scans)
+ opt.check_range_access();
+
+ opt.get_best_option();
+ }
+*/
+
+class Loose_scan_opt
+{
+public:
+ /* All methods must check this before doing anything else */
+ bool try_loosescan;
+
+ /*
+ If we consider (oe1, .. oeN) IN (SELECT ie1, .. ieN) then ieK=oeK is
+ called sj-equality. If oeK depends only on preceding tables then such
+ equality is called 'bound'.
+ */
+ ulonglong bound_sj_equalities;
+
+ /* Accumulated properties of ref access we're now considering: */
+ ulonglong handled_sj_equalities;
+ key_part_map loose_scan_keyparts;
+ uint max_loose_keypart;
+ bool part1_conds_met;
+
+ /*
+ Use of quick select is a special case. Some of its properties:
+ */
+ uint quick_uses_applicable_index;
+ uint quick_max_loose_keypart;
+
+ /* Best loose scan method so far */
+ uint best_loose_scan_key;
+ double best_loose_scan_cost;
+ double best_loose_scan_records;
+ KEYUSE *best_loose_scan_start_key;
+
+ uint best_max_loose_keypart;
+
+ Loose_scan_opt():
+ try_loosescan(FALSE),
+ bound_sj_equalities(0),
+ quick_uses_applicable_index(FALSE)
+ {
+ UNINIT_VAR(quick_max_loose_keypart); /* Protected by quick_uses_applicable_index */
+ /* The following are protected by best_loose_scan_cost!= DBL_MAX */
+ UNINIT_VAR(best_loose_scan_key);
+ UNINIT_VAR(best_loose_scan_records);
+ UNINIT_VAR(best_max_loose_keypart);
+ UNINIT_VAR(best_loose_scan_start_key);
+ }
+
+ void init(JOIN *join, JOIN_TAB *s, table_map remaining_tables)
+ {
+ /*
+ Discover the bound equalities. We need to do this if
+ 1. The next table is an SJ-inner table, and
+ 2. It is the first table from that semijoin, and
+ 3. We're not within a semi-join range (i.e. all semi-joins either have
+ all or none of their tables in join_table_map), except
+ s->emb_sj_nest (which we've just entered, see #2).
+ 4. All non-IN-equality correlation references from this sj-nest are
+ bound
+ 5. But some of the IN-equalities aren't (so this can't be handled by
+ FirstMatch strategy)
+ */
+ best_loose_scan_cost= DBL_MAX;
+ if (!join->emb_sjm_nest && s->emb_sj_nest && // (1)
+ s->emb_sj_nest->sj_in_exprs < 64 &&
+ ((remaining_tables & s->emb_sj_nest->sj_inner_tables) == // (2)
+ s->emb_sj_nest->sj_inner_tables) && // (2)
+ join->cur_sj_inner_tables == 0 && // (3)
+ !(remaining_tables &
+ s->emb_sj_nest->nested_join->sj_corr_tables) && // (4)
+ remaining_tables & s->emb_sj_nest->nested_join->sj_depends_on &&// (5)
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_LOOSE_SCAN))
+ {
+ /* This table is an LooseScan scan candidate */
+ bound_sj_equalities= get_bound_sj_equalities(s->emb_sj_nest,
+ remaining_tables);
+ try_loosescan= TRUE;
+ DBUG_PRINT("info", ("Will try LooseScan scan, bound_map=%llx",
+ (longlong)bound_sj_equalities));
+ }
+ }
+
+ void next_ref_key()
+ {
+ handled_sj_equalities=0;
+ loose_scan_keyparts= 0;
+ max_loose_keypart= 0;
+ part1_conds_met= FALSE;
+ }
+
+ void add_keyuse(table_map remaining_tables, KEYUSE *keyuse)
+ {
+ if (try_loosescan && keyuse->sj_pred_no != UINT_MAX)
+ {
+ if (!(remaining_tables & keyuse->used_tables))
+ {
+ /*
+ This allows to use equality propagation to infer that some
+ sj-equalities are bound.
+ */
+ bound_sj_equalities |= 1ULL << keyuse->sj_pred_no;
+ }
+ else
+ {
+ handled_sj_equalities |= 1ULL << keyuse->sj_pred_no;
+ loose_scan_keyparts |= ((key_part_map)1) << keyuse->keypart;
+ set_if_bigger(max_loose_keypart, keyuse->keypart);
+ }
+ }
+ }
+
+ bool have_a_case() { return test(handled_sj_equalities); }
+
+ void check_ref_access_part1(JOIN_TAB *s, uint key, KEYUSE *start_key,
+ table_map found_part)
+ {
+ /*
+ Check if we can use LooseScan semi-join strategy. We can if
+ 1. This is the right table at right location
+ 2. All IN-equalities are either
+ - "bound", ie. the outer_expr part refers to the preceding tables
+ - "handled", ie. covered by the index we're considering
+ 3. Index order allows to enumerate subquery's duplicate groups in
+ order. This happens when the index definition matches this
+ pattern:
+
+ (handled_col|bound_col)* (other_col|bound_col)
+
+ */
+ if (try_loosescan && // (1)
+ (handled_sj_equalities | bound_sj_equalities) == // (2)
+ PREV_BITS(ulonglong, s->emb_sj_nest->sj_in_exprs) && // (2)
+ (PREV_BITS(key_part_map, max_loose_keypart+1) & // (3)
+ (found_part | loose_scan_keyparts)) == // (3)
+ (found_part | loose_scan_keyparts) && // (3)
+ !key_uses_partial_cols(s->table, key))
+ {
+ /* Ok, can use the strategy */
+ part1_conds_met= TRUE;
+ if (s->quick && s->quick->index == key &&
+ s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE)
+ {
+ quick_uses_applicable_index= TRUE;
+ quick_max_loose_keypart= max_loose_keypart;
+ }
+ DBUG_PRINT("info", ("Can use LooseScan scan"));
+
+ /*
+ Check if this is a special case where there are no usable bound
+ IN-equalities, i.e. we have
+
+ outer_expr IN (SELECT innertbl.key FROM ...)
+
+ and outer_expr cannot be evaluated yet, so it's actually full
+ index scan and not a ref access
+ */
+ if (!(found_part & 1 ) && /* no usable ref access for 1st key part */
+ s->table->covering_keys.is_set(key))
+ {
+ DBUG_PRINT("info", ("Can use full index scan for LooseScan"));
+
+ /* Calculate the cost of complete loose index scan. */
+ double records= rows2double(s->table->file->stats.records);
+
+ /* The cost is entire index scan cost (divided by 2) */
+ double read_time= s->table->file->keyread_time(key, 1,
+ (ha_rows) records);
+
+ /*
+ Now find out how many different keys we will get (for now we
+ ignore the fact that we have "keypart_i=const" restriction for
+ some key components, that may make us think think that loose
+ scan will produce more distinct records than it actually will)
+ */
+ ulong rpc;
+ if ((rpc= s->table->key_info[key].rec_per_key[max_loose_keypart]))
+ records= records / rpc;
+
+ // TODO: previous version also did /2
+ if (read_time < best_loose_scan_cost)
+ {
+ best_loose_scan_key= key;
+ best_loose_scan_cost= read_time;
+ best_loose_scan_records= records;
+ best_max_loose_keypart= max_loose_keypart;
+ best_loose_scan_start_key= start_key;
+ }
+ }
+ }
+ }
+
+ void check_ref_access_part2(uint key, KEYUSE *start_key, double records,
+ double read_time)
+ {
+ if (part1_conds_met && read_time < best_loose_scan_cost)
+ {
+ /* TODO use rec-per-key-based fanout calculations */
+ best_loose_scan_key= key;
+ best_loose_scan_cost= read_time;
+ best_loose_scan_records= records;
+ best_max_loose_keypart= max_loose_keypart;
+ best_loose_scan_start_key= start_key;
+ }
+ }
+
+ void check_range_access(JOIN *join, uint idx, QUICK_SELECT_I *quick)
+ {
+ /* TODO: this the right part restriction: */
+ if (quick_uses_applicable_index && idx == join->const_tables &&
+ quick->read_time < best_loose_scan_cost)
+ {
+ best_loose_scan_key= quick->index;
+ best_loose_scan_cost= quick->read_time;
+ /* this is ok because idx == join->const_tables */
+ best_loose_scan_records= rows2double(quick->records);
+ best_max_loose_keypart= quick_max_loose_keypart;
+ best_loose_scan_start_key= NULL;
+ }
+ }
+
+ void save_to_position(JOIN_TAB *tab, POSITION *pos)
+ {
+ pos->read_time= best_loose_scan_cost;
+ if (best_loose_scan_cost != DBL_MAX)
+ {
+ pos->records_read= best_loose_scan_records;
+ pos->key= best_loose_scan_start_key;
+ pos->loosescan_key= best_loose_scan_key;
+ pos->loosescan_parts= best_max_loose_keypart + 1;
+ pos->use_join_buffer= FALSE;
+ pos->table= tab;
+ // todo need ref_depend_map ?
+ DBUG_PRINT("info", ("Produced a LooseScan plan, key %s, %s",
+ tab->table->key_info[best_loose_scan_key].name,
+ best_loose_scan_start_key? "(ref access)":
+ "(range/index access)"));
+ }
+ }
+};
+
+
+void advance_sj_state(JOIN *join, const table_map remaining_tables,
+ const JOIN_TAB *new_join_tab, uint idx,
+ double *current_record_count, double *current_read_time,
+ POSITION *loose_scan_pos);
+void restore_prev_sj_state(const table_map remaining_tables,
+ const JOIN_TAB *tab, uint idx);
+
+void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
+bool setup_sj_materialization(JOIN_TAB *tab);
+
+TABLE *create_duplicate_weedout_tmp_table(THD *thd, uint uniq_tuple_length_arg,
+ SJ_TMP_TABLE *sjtbl);
+int do_sj_reset(SJ_TMP_TABLE *sj_tbl);
+int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl);
+
+/*
+ Temporary table used by semi-join DuplicateElimination strategy
+
+ This consists of the temptable itself and data needed to put records
+ into it. The table's DDL is as follows:
+
+ CREATE TABLE tmptable (col VARCHAR(n) BINARY, PRIMARY KEY(col));
+
+ where the primary key can be replaced with unique constraint if n exceeds
+ the limit (as it is always done for query execution-time temptables).
+
+ The record value is a concatenation of rowids of tables from the join we're
+ executing. If a join table is on the inner side of the outer join, we
+ assume that its rowid can be NULL and provide means to store this rowid in
+ the tuple.
+*/
+
+class SJ_TMP_TABLE : public Sql_alloc
+{
+public:
+ /*
+ Array of pointers to tables whose rowids compose the temporary table
+ record.
+ */
+ class TAB
+ {
+ public:
+ JOIN_TAB *join_tab;
+ uint rowid_offset;
+ ushort null_byte;
+ uchar null_bit;
+ };
+ TAB *tabs;
+ TAB *tabs_end;
+
+ /*
+ is_degenerate==TRUE means this is a special case where the temptable record
+ has zero length (and presence of a unique key means that the temptable can
+ have either 0 or 1 records).
+ In this case we don't create the physical temptable but instead record
+ its state in SJ_TMP_TABLE::have_degenerate_row.
+ */
+ bool is_degenerate;
+
+ /*
+ When is_degenerate==TRUE: the contents of the table (whether it has the
+ record or not).
+ */
+ bool have_degenerate_row;
+
+ /* table record parameters */
+ uint null_bits;
+ uint null_bytes;
+ uint rowid_len;
+
+ /* The temporary table itself (NULL means not created yet) */
+ TABLE *tmp_table;
+
+ /*
+ These are the members we got from temptable creation code. We'll need
+ them if we'll need to convert table from HEAP to MyISAM/Maria.
+ */
+ ENGINE_COLUMNDEF *start_recinfo;
+ ENGINE_COLUMNDEF *recinfo;
+
+ /* Pointer to next table (next->start_idx > this->end_idx) */
+ SJ_TMP_TABLE *next;
+};
+
+int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
+ uint no_jbuf_after);
+void destroy_sj_tmp_tables(JOIN *join);
+int clear_sj_tmp_tables(JOIN *join);
+int rewrite_to_index_subquery_engine(JOIN *join);
+
+
+
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index 174dcbf9c13..be1471b7e2c 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -725,7 +725,11 @@ eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list,
}
else
{
- DBUG_ASSERT(!tbl->nested_join);
+ DBUG_ASSERT(!tbl->nested_join || tbl->sj_on_expr);
+ //psergey-todo: is the following really correct or we'll need to descend
+ //down all ON clauses: ?
+ if (tbl->sj_on_expr)
+ tables_used_on_left |= tbl->sj_on_expr->used_tables();
}
}
@@ -918,8 +922,9 @@ public:
Field_dependency_recorder(Dep_analysis_context *ctx_arg): ctx(ctx_arg)
{}
- void visit_field(Field *field)
+ void visit_field(Item_field *item)
{
+ Field *field= item->field;
Dep_value_table *tbl_dep;
if ((tbl_dep= ctx->table_deps[field->table->tablenr]))
{
@@ -1778,7 +1783,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl)
JOIN_TAB *tab= tbl->table->reginfo.join_tab;
if (!(join->const_table_map & tab->table->map))
{
- DBUG_PRINT("info", ("Eliminated table %s", table->alias));
+ DBUG_PRINT("info", ("Eliminated table %s", table->alias.c_ptr()));
tab->type= JT_CONST;
join->eliminated_tables |= table->map;
join->const_table_map|= table->map;
@@ -1813,7 +1818,7 @@ void Dep_analysis_context::dbug_print_deps()
fprintf(DBUG_FILE, " equality%ld: %s -> %s.%s\n",
(long)(eq_mod - equality_mods),
str.c_ptr(),
- eq_mod->field->table->table->alias,
+ eq_mod->field->table->table->alias.c_ptr(),
eq_mod->field->field->field_name);
}
else
@@ -1831,12 +1836,13 @@ void Dep_analysis_context::dbug_print_deps()
if ((table_dep= table_deps[i]))
{
/* Print table */
- fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias);
+ fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias.c_ptr());
/* Print fields */
for (Dep_value_field *field_dep= table_dep->fields; field_dep;
field_dep= field_dep->next_table_field)
{
- fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias,
+ fprintf(DBUG_FILE, " field %s.%s ->",
+ table_dep->table->alias.c_ptr(),
field_dep->field->field_name);
uint ofs= field_dep->bitmap_offset;
for (uint bit= ofs; bit < ofs + n_equality_mods; bit++)
diff --git a/sql/procedure.h b/sql/procedure.h
index 30a8a0efccb..488d461905e 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -13,6 +13,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#ifndef PROCEDURE_INCLUDED
+#define PROCEDURE_INCLUDED
/* When using sql procedures */
@@ -153,3 +155,5 @@ public:
Procedure *setup_procedure(THD *thd,ORDER *proc_param,select_result *result,
List<Item> &field_list,int *error);
+
+#endif /* PROCEDURE_INCLUDED */
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 8a9d712077d..70b171fa652 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -632,6 +632,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
uint count= 0;
#endif
+ /* We have to reallocate it here as a stored procedure may have reset it */
+ (void) local_packet->alloc(thd->variables.net_buffer_length);
+
while ((item=it++))
{
char *pos;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 910deafc432..ee0e870cd93 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -320,6 +320,11 @@ static sys_var_thd_ulong sys_interactive_timeout(&vars, "interactive_timeout",
&SV::net_interactive_timeout);
static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size",
&SV::join_buff_size);
+static sys_var_thd_ulonglong sys_join_buffer_space_limit(&vars,
+ "join_buffer_space_limit",
+ &SV::join_buff_space_limit);
+static sys_var_thd_ulong sys_join_cache_level(&vars, "join_cache_level",
+ &SV::join_cache_level);
static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size");
static sys_var_key_cache_long sys_key_cache_block_size(&vars,
"key_cache_block_size",
@@ -449,8 +454,6 @@ static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
&max_write_lock_count);
static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit",
&SV::min_examined_row_limit);
-static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count",
- &SV::multi_range_count);
static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size",
&myisam_data_pointer_size);
static sys_var_thd_ulonglong sys_myisam_max_sort_file_size(&vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
@@ -503,6 +506,18 @@ static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_sea
&SV::optimizer_search_depth);
static sys_var_thd_optimizer_switch sys_optimizer_switch(&vars, "optimizer_switch",
&SV::optimizer_switch);
+
+const char *optimizer_use_mrr_names[] = {"auto", "force", "disable", NullS};
+TYPELIB optimizer_use_mrr_typelib= {
+ array_elements(optimizer_use_mrr_names) - 1, "",
+ optimizer_use_mrr_names, NULL
+};
+
+static sys_var_thd_enum sys_optimizer_use_mrr(&vars, "optimizer_use_mrr",
+ &SV::optimizer_use_mrr,
+ &optimizer_use_mrr_typelib,
+ NULL);
+
static sys_var_const sys_pid_file(&vars, "pid_file",
OPT_GLOBAL, SHOW_CHAR,
(uchar*) pidfile_name);
@@ -526,6 +541,8 @@ static sys_var_bool_ptr sys_userstat(&vars, "userstat",
static sys_var_thd_ulong sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
&SV::read_rnd_buff_size);
+static sys_var_thd_ulong sys_mrr_buff_size(&vars, "mrr_buffer_size",
+ &SV::mrr_buff_size);
static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
&SV::div_precincrement);
static sys_var_long_ptr sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
@@ -536,6 +553,9 @@ static sys_var_long_ptr sys_query_cache_size(&vars, "query_cache_size",
static sys_var_thd_ulong sys_range_alloc_block_size(&vars, "range_alloc_block_size",
&SV::range_alloc_block_size);
+static sys_var_thd_ulong sys_rowid_merge_buff_size(&vars, "rowid_merge_buff_size",
+ &SV::rowid_merge_buff_size);
+
static sys_var_thd_ulong sys_query_alloc_block_size(&vars, "query_alloc_block_size",
&SV::query_alloc_block_size,
0, fix_thd_mem_root);
@@ -975,7 +995,7 @@ bool sys_var_str::check(THD *thd, set_var *var)
if ((res=(*check_func)(thd, var)) < 0)
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
- name, var->value->str_value.ptr());
+ name, var->value->str_value.c_ptr());
return res;
}
@@ -2266,11 +2286,15 @@ bool sys_var_character_set::check(THD *thd, set_var *var)
}
tmp= NULL;
}
- else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) &&
- !(tmp=get_old_charset_by_name(res->c_ptr())))
+ else
{
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
- return 1;
+ const char *name= res->c_ptr_safe();
+ if (!(tmp=get_charset_by_csname(name,MY_CS_PRIMARY,MYF(0))) &&
+ !(tmp=get_old_charset_by_name(name)))
+ {
+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
+ return 1;
+ }
}
}
else // INT_RESULT
@@ -2607,7 +2631,7 @@ static int sys_check_log_path(THD *thd, set_var *var)
if (!(res= var->value->val_str(&str)))
goto err;
- log_file_str= res->c_ptr();
+ log_file_str= res->c_ptr_safe();
bzero(&f_stat, sizeof(MY_STAT));
path_length= unpack_filename(path, log_file_str);
@@ -3070,7 +3094,7 @@ bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
return 1;
}
- const char *locale_str= res->c_ptr();
+ const char *locale_str= res->c_ptr_safe();
if (!(locale_match= my_locale_by_name(locale_str)))
{
my_printf_error(ER_UNKNOWN_ERROR,
@@ -4037,7 +4061,7 @@ bool
sys_var_thd_optimizer_switch::
symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
{
- char buff[STRING_BUFFER_USUAL_SIZE*8];
+ char buff[STRING_BUFFER_USUAL_SIZE*18];
String tmp(buff, sizeof(buff), &my_charset_latin1);
int i;
ulonglong bit;
@@ -4102,7 +4126,7 @@ bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var)
optimizer_switch_typelib.count,
thd->variables.optimizer_switch,
global_system_variables.optimizer_switch,
- res->c_ptr_safe(), res->length(), NULL,
+ res->ptr(), res->length(), NULL,
&error, &error_len, &not_used);
if (error_len)
{
diff --git a/sql/sp.cc b/sql/sp.cc
index 68e2f19fd47..d2c732c2100 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1104,7 +1104,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
(sp->m_explicit_name ? sp->m_db.length : 0),
sp->m_name.str, sp->m_name.length,
sp->m_params.str, sp->m_params.length,
- retstr.c_ptr(), retstr.length(),
+ retstr.ptr(), retstr.length(),
sp->m_body.str, sp->m_body.length,
sp->m_chistics, &(thd->lex->definer->user),
&(thd->lex->definer->host)))
@@ -1116,7 +1116,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
thd->variables.sql_mode= saved_mode;
/* Such a statement can always go directly to binlog, no trans cache */
if (thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- log_query.c_ptr(), log_query.length(),
+ log_query.ptr(), log_query.length(),
FALSE, FALSE, 0))
ret= SP_INTERNAL_ERROR;
thd->variables.sql_mode= 0;
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index be8f705a53e..686e1a1346f 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -118,7 +118,7 @@ sp_rcontext::init_var_table(THD *thd)
return TRUE;
m_var_table->copy_blobs= TRUE;
- m_var_table->alias= "";
+ m_var_table->alias.set("", 0, table_alias_charset);
return FALSE;
}
diff --git a/sql/sql_array.h b/sql/sql_array.h
index e1b22921519..233b3f24263 100644
--- a/sql/sql_array.h
+++ b/sql/sql_array.h
@@ -66,3 +66,75 @@ public:
}
};
+
+/*
+ Array of pointers to Elem that uses memory from MEM_ROOT
+
+ MEM_ROOT has no realloc() so this is supposed to be used for cases when
+ reallocations are rare.
+*/
+
+template <class Elem> class Array
+{
+ enum {alloc_increment = 16};
+ Elem **buffer;
+ uint n_elements, max_element;
+public:
+ Array(MEM_ROOT *mem_root, uint prealloc=16)
+ {
+ buffer= (Elem**)alloc_root(mem_root, prealloc * sizeof(Elem**));
+ max_element = buffer? prealloc : 0;
+ n_elements= 0;
+ }
+
+ Elem& at(int idx)
+ {
+ return *(((Elem*)buffer) + idx);
+ }
+
+ Elem **front()
+ {
+ return buffer;
+ }
+
+ Elem **back()
+ {
+ return buffer + n_elements;
+ }
+
+ bool append(MEM_ROOT *mem_root, Elem *el)
+ {
+ if (n_elements == max_element)
+ {
+ Elem **newbuf;
+ if (!(newbuf= (Elem**)alloc_root(mem_root, (n_elements + alloc_increment)*
+ sizeof(Elem**))))
+ {
+ return FALSE;
+ }
+ memcpy(newbuf, buffer, n_elements*sizeof(Elem*));
+ buffer= newbuf;
+ }
+ buffer[n_elements++]= el;
+ return FALSE;
+ }
+
+ int elements()
+ {
+ return n_elements;
+ }
+
+ void clear()
+ {
+ n_elements= 0;
+ }
+
+ typedef int (*CMP_FUNC)(Elem * const *el1, Elem *const *el2);
+
+ void sort(CMP_FUNC cmp_func)
+ {
+ my_qsort(buffer, n_elements, sizeof(Elem*), (qsort_cmp)cmp_func);
+ }
+};
+
+
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a1458259d11..01c72db0c8e 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -22,6 +22,7 @@
#include "sp_head.h"
#include "sp.h"
#include "sql_trigger.h"
+#include "sql_handler.h"
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
@@ -1381,10 +1382,10 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
bool found_old_table= 0;
TABLE *table= *table_ptr;
DBUG_ENTER("close_thread_table");
- DBUG_ASSERT(table->key_read == 0);
- DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
table->s->table_name.str, (long) table));
+ DBUG_ASSERT(table->key_read == 0);
+ DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
if (table->file)
{
@@ -1474,12 +1475,11 @@ void close_temporary_tables(THD *thd)
/* Better add "if exists", in case a RESET MASTER has been done */
const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
- uint stub_len= sizeof(stub) - 1;
- char buf[256];
- String s_query= String(buf, sizeof(buf), system_charset_info);
+ char buf[FN_REFLEN];
+ String s_query(buf, sizeof(buf), system_charset_info);
bool found_user_tables= FALSE;
- memcpy(buf, stub, stub_len);
+ s_query.copy(stub, sizeof(stub)-1, system_charset_info);
/*
Insertion sort of temp tables by pseudo_thread_id to build ordered list
@@ -1533,19 +1533,24 @@ void close_temporary_tables(THD *thd)
{
bool save_thread_specific_used= thd->thread_specific_used;
my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
+ char db_buf[FN_REFLEN];
+ String db(db_buf, sizeof(db_buf), system_charset_info);
+
/* Set pseudo_thread_id to be that of the processed table */
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
- String db;
- db.append(table->s->db.str);
+
+ db.copy(table->s->db.str, table->s->db.length, system_charset_info);
+ s_query.length(sizeof(stub)-1);
+
/* Loop forward through all tables that belong to a common database
within the sublist of common pseudo_thread_id to create single
DROP query
*/
- for (s_query.length(stub_len);
+ for (;
table && is_user_table(table) &&
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id &&
table->s->db.length == db.length() &&
- strcmp(table->s->db.str, db.ptr()) == 0;
+ memcmp(table->s->db.str, db.ptr(), db.length()) == 0;
table= next)
{
/*
@@ -1849,7 +1854,7 @@ int drop_temporary_table(THD *thd, TABLE_LIST *table_list)
/* Table might be in use by some outer statement. */
if (table->query_id && table->query_id != thd->query_id)
{
- my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
+ my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr());
DBUG_RETURN(-1);
}
@@ -1872,7 +1877,7 @@ void close_temporary_table(THD *thd, TABLE *table,
DBUG_ENTER("close_temporary_table");
DBUG_PRINT("tmptable", ("closing table: '%s'.'%s' 0x%lx alias: '%s'",
table->s->db.str, table->s->table_name.str,
- (long) table, table->alias));
+ (long) table, table->alias.c_ptr()));
/*
When closing a MERGE parent or child table, detach the children
@@ -2606,7 +2611,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
("query_id: %lu server_id: %u pseudo_thread_id: %lu",
(ulong) table->query_id, (uint) thd->server_id,
(ulong) thd->variables.pseudo_thread_id));
- my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
+ my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr());
DBUG_RETURN(0);
}
table->query_id= thd->query_id;
@@ -2643,7 +2648,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
When looking for a usable TABLE, ignore MERGE children, as they
belong to their parent and cannot be used explicitly.
*/
- if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
+ if (!my_strcasecmp(system_charset_info, table->alias.c_ptr(), alias) &&
table->query_id != thd->query_id && /* skip tables already used */
!(thd->prelocked_mode && table->query_id) &&
!table->parent)
@@ -2999,13 +3004,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->alias_name_used= my_strcasecmp(table_alias_charset,
table->s->table_name.str, alias);
/* Fix alias if table name changes */
- if (strcmp(table->alias, alias))
- {
- uint length=(uint) strlen(alias)+1;
- table->alias= (char*) my_realloc((char*) table->alias, length,
- MYF(MY_WME));
- memcpy((char*) table->alias, alias, length);
- }
+ if (strcmp(table->alias.c_ptr(), alias))
+ table->alias.copy(alias, strlen(alias), table->alias.charset());
+
/* These variables are also set in reopen_table() */
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
@@ -3026,13 +3027,19 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->pos_in_table_list= table_list;
table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
table->clear_column_bitmaps();
-#if !defined(DBUG_OFF) && !defined(HAVE_valgrind)
/*
Fill record with random values to find bugs where we access fields
without first reading them.
*/
- bfill(table->record[0], table->s->reclength, 254);
-#endif
+ TRASH(table->record[0], table->s->reclength);
+ /*
+ Initialize the null marker bits, to ensure that if we are doing a read
+ of only selected columns (like in keyread), all null markers are
+ initialized.
+ */
+ bfill(table->record[0], table->s->null_bytes, 255);
+ bfill(table->record[1], table->s->null_bytes, 255);
+
DBUG_ASSERT(table->key_read == 0);
DBUG_RETURN(table);
}
@@ -3089,7 +3096,7 @@ bool reopen_table(TABLE *table)
#ifdef EXTRA_DEBUG
if (table->db_stat)
sql_print_error("Table %s had a open data handler in reopen_table",
- table->alias);
+ table->alias.c_ptr());
#endif
bzero((char*) &table_list, sizeof(TABLE_LIST));
table_list.db= table->s->db.str;
@@ -3100,7 +3107,7 @@ bool reopen_table(TABLE *table)
DBUG_RETURN(1); // Thread was killed
if (open_unireg_entry(thd, &tmp, &table_list,
- table->alias,
+ table->alias.c_ptr(),
table->s->table_cache_key.str,
table->s->table_cache_key.length,
thd->mem_root, 0))
@@ -3139,14 +3146,14 @@ bool reopen_table(TABLE *table)
VOID(closefrm(table, 1)); // close file, free everything
*table= tmp;
+ table->alias.move(tmp.alias);
table->default_column_bitmaps();
table->file->change_table_ptr(table, table->s);
- DBUG_ASSERT(table->alias != 0);
+ DBUG_ASSERT(table->alias.ptr() != 0);
for (field=table->field ; *field ; field++)
{
- (*field)->table= (*field)->orig_table= table;
- (*field)->table_name= &table->alias;
+ (*field)->init(table);
}
for (key=0 ; key < table->s->keys ; key++)
{
@@ -3273,7 +3280,7 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
DBUG_PRINT("tcache", ("MERGE parent, attach children"));
if(table->file->extra(HA_EXTRA_ATTACH_CHILDREN))
{
- my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
+ my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr());
error= TRUE;
/* Remove table from open_tables. */
*prv_p= next;
@@ -3366,7 +3373,8 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
if (!tables || (!db_stat && reopen_table(table)))
{
my_error(ER_CANT_REOPEN_TABLE, MYF(0),
- table->alias ? table->alias : table->s->table_name.str);
+ table->alias.ptr() ? table->alias.c_ptr() :
+ table->s->table_name.str);
/*
If we could not allocate 'tables', we may close open tables
here. If a MERGE table is affected, detach the children first.
@@ -3563,7 +3571,8 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
char *key= table->s->table_cache_key.str;
uint key_length= table->s->table_cache_key.length;
- DBUG_PRINT("loop", ("table_name: %s", table->alias ? table->alias : ""));
+ DBUG_PRINT("loop", ("table_name: %s",
+ table->alias.ptr() ? table->alias.c_ptr() : ""));
HASH_SEARCH_STATE state;
for (TABLE *search= (TABLE*) hash_first(&open_cache, (uchar*) key,
key_length, &state);
@@ -4357,7 +4366,7 @@ void detach_merge_children(TABLE *table, bool clear_refs)
Set alias to "" to ensure that table is not used if we are in
LOCK TABLES
*/
- ((char*) child_l->table->alias)[0]= 0;
+ child_l->table->alias.copy("", 0, child_l->table->alias.charset());
/* Clear the table reference to force new assignment at next open. */
child_l->table= NULL;
@@ -4910,7 +4919,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ &&
(int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ)
{
- my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias);
+ my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias.c_ptr());
DBUG_RETURN(1);
}
if ((error=table->file->start_stmt(thd, lock_type)))
@@ -6022,7 +6031,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
Field **field_ptr, *field;
uint cached_field_index= *cached_field_index_ptr;
DBUG_ENTER("find_field_in_table");
- DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias, name));
+ DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias.c_ptr(),
+ name));
/* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */
if (cached_field_index < table->s->fields &&
@@ -6406,12 +6416,21 @@ find_field_in_tables(THD *thd, Item_ident *item,
sub query as dependent on the outer query
*/
if (current_sel != last_select)
+ {
mark_select_range_as_dependent(thd, last_select, current_sel,
found, *ref, item);
+ if (item->can_be_depended)
+ {
+ DBUG_ASSERT((*ref) == (Item*)item);
+ current_sel->register_dependency_item(last_select, ref);
+ }
+ }
}
return found;
}
}
+ else
+ item->can_be_depended= TRUE;
if (db && lower_case_table_names)
{
@@ -8126,6 +8145,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
SELECT_LEX *select_lex= thd->lex->current_select;
Query_arena *arena= thd->stmt_arena, backup;
TABLE_LIST *table= NULL; // For HP compilers
+ TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
/*
it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
which belong to LEX, i.e. most up SELECT) will be updated by
@@ -8156,13 +8176,19 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
goto err_no_arena;
}
+ thd->thd_marker.emb_on_expr_nest= (TABLE_LIST*)1;
if (*conds)
{
thd->where="where clause";
+ DBUG_EXECUTE("where",
+ print_where(*conds,
+ "WHERE in setup_conds",
+ QT_ORDINARY););
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,
@@ -8178,6 +8204,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, 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";
if ((!embedded->on_expr->fixed &&
embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
@@ -8202,6 +8229,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
}
}
}
+ thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest;
if (!thd->stmt_arena->is_conventional())
{
@@ -8416,6 +8444,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
ptr pointer on pointer to record
values list of fields
ignore_errors TRUE if we should ignore errors
+ use_value forces usage of value of the items instead of result
NOTE
fill_record() may set table->auto_increment_field_not_null and a
@@ -8428,7 +8457,8 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
*/
bool
-fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
+fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
+ bool use_value)
{
List_iterator_fast<Item> v(values);
List<TABLE> tbl_list;
@@ -8470,8 +8500,11 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
field->field_name, table->s->table_name.str);
thd->abort_on_warning= abort_on_warning_saved;
}
- if (value->save_in_field(field, 0) < 0)
- goto err;
+ if (use_value)
+ value->save_val(field);
+ else
+ if (value->save_in_field(field, 0) < 0)
+ goto err;
tbl_list.push_back(table);
}
/* Update virtual fields*/
@@ -8540,7 +8573,7 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
enum trg_event_type event)
{
bool result;
- result= (fill_record(thd, ptr, values, ignore_errors) ||
+ result= (fill_record(thd, ptr, values, ignore_errors, FALSE) ||
(triggers && triggers->process_triggers(thd, event,
TRG_ACTION_BEFORE, TRUE)));
/*
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b64a5a71514..11447389186 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -42,7 +42,9 @@
#include "sp_rcontext.h"
#include "sp_cache.h"
+#include "sql_select.h" /* declares create_tmp_table() */
#include "debug_sync.h"
+#include "sql_handler.h"
/*
The following is used to initialise Table_ident with a internal
@@ -701,7 +703,7 @@ THD::THD()
catalog= (char*)"std"; // the only catalog we have for now
main_security_ctx.init();
security_ctx= &main_security_ctx;
- locked=some_tables_deleted=no_errors=password= 0;
+ some_tables_deleted=no_errors=password= 0;
query_start_used= 0;
count_cuted_fields= CHECK_FIELD_IGNORE;
killed= NOT_KILLED;
@@ -1190,6 +1192,8 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
/* Handle the not ulong variables. See end of system_status_var */
to_var->bytes_received= from_var->bytes_received;
to_var->bytes_sent+= from_var->bytes_sent;
+ to_var->rows_read+= from_var->rows_read;
+ to_var->rows_sent+= from_var->rows_sent;
to_var->binlog_bytes_written= from_var->binlog_bytes_written;
to_var->cpu_time+= from_var->cpu_time;
to_var->busy_time+= from_var->busy_time;
@@ -2394,7 +2398,6 @@ bool select_export::send_data(List<Item> &items)
{ // Fill with space
if (item->max_length > used_length)
{
- /* QQ: Fix by adding a my_b_fill() function */
if (!space_inited)
{
space_inited=1;
@@ -3030,6 +3033,92 @@ bool select_dumpvar::send_eof()
return 0;
}
+
+bool
+select_materialize_with_stats::
+create_result_table(THD *thd_arg, List<Item> *column_types,
+ bool is_union_distinct, ulonglong options,
+ const char *table_alias, bool bit_fields_as_long)
+{
+ DBUG_ASSERT(table == 0);
+ tmp_table_param.field_count= column_types->elements;
+ tmp_table_param.bit_fields_as_long= bit_fields_as_long;
+
+ if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
+ (ORDER*) 0, is_union_distinct, 1,
+ options, HA_POS_ERROR, (char*) table_alias)))
+ return TRUE;
+
+ col_stat= (Column_statistics*) table->in_use->alloc(table->s->fields *
+ sizeof(Column_statistics));
+ if (!col_stat)
+ return TRUE;
+
+ reset();
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ return FALSE;
+}
+
+
+void select_materialize_with_stats::reset()
+{
+ memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
+ max_nulls_in_row= 0;
+ count_rows= 0;
+}
+
+
+void select_materialize_with_stats::cleanup()
+{
+ reset();
+ select_union::cleanup();
+}
+
+
+/**
+ Override select_union::send_data to analyze each row for NULLs and to
+ update null_statistics before sending data to the client.
+
+ @return TRUE if fatal error when sending data to the client
+ @return FALSE on success
+*/
+
+bool select_materialize_with_stats::send_data(List<Item> &items)
+{
+ List_iterator_fast<Item> item_it(items);
+ Item *cur_item;
+ Column_statistics *cur_col_stat= col_stat;
+ uint nulls_in_row= 0;
+
+ if (select_union::send_data(items))
+ return 1;
+ /* Skip duplicate rows. */
+ if (write_err == HA_ERR_FOUND_DUPP_KEY ||
+ write_err == HA_ERR_FOUND_DUPP_UNIQUE)
+ return 0;
+
+ ++count_rows;
+
+ while ((cur_item= item_it++))
+ {
+ if (cur_item->is_null())
+ {
+ ++cur_col_stat->null_count;
+ cur_col_stat->max_null_row= count_rows;
+ if (!cur_col_stat->min_null_row)
+ cur_col_stat->min_null_row= count_rows;
+ ++nulls_in_row;
+ }
+ ++cur_col_stat;
+ }
+ if (nulls_in_row > max_nulls_in_row)
+ max_nulls_in_row= nulls_in_row;
+
+ return 0;
+}
+
+
/****************************************************************************
TMP_TABLE_PARAM
****************************************************************************/
@@ -3043,6 +3132,8 @@ void TMP_TABLE_PARAM::init()
quick_group= 1;
table_charset= 0;
precomputed_group_by= 0;
+ bit_fields_as_long= 0;
+ skip_create_table= 0;
DBUG_VOID_RETURN;
}
@@ -4065,8 +4156,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
int errcode)
{
DBUG_ENTER("THD::binlog_query");
- DBUG_PRINT("enter", ("qtype: %s query: '%s'",
- show_query_type(qtype), query_arg));
+ DBUG_PRINT("enter", ("qtype: %s query: '%-.*s'",
+ show_query_type(qtype), (int) query_len, query_arg));
DBUG_ASSERT(query_arg && mysql_bin_log.is_open());
/*
@@ -4102,7 +4193,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
{
sql_print_warning("%s Statement: %.*s",
ER(ER_BINLOG_UNSAFE_STATEMENT),
- MYSQL_ERRMSG_SIZE, query_arg);
+ (int) min(MYSQL_ERRMSG_SIZE, query_len), query_arg);
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
}
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2fe579713e1..8e0f1664286 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -23,6 +23,76 @@
#include "log.h"
#include "rpl_tblmap.h"
+
+/**
+ Interface for Item iterator
+*/
+
+class Item_iterator
+{
+public:
+ /**
+ Shall set this iterator to the position before the first item
+
+ @note
+ This method also may perform some other initialization actions like
+ allocation of certain resources.
+ */
+ virtual void open()= 0;
+ /**
+ Shall return the next Item (or NULL if there is no next item) and
+ move pointer to position after it.
+ */
+ virtual Item *next()= 0;
+ /**
+ Shall force iterator to free resources (if it holds them)
+
+ @note
+ One should not use the iterator without open() call after close()
+ */
+ virtual void close()= 0;
+
+ virtual ~Item_iterator() {}
+};
+
+
+/**
+ Item iterator over List_iterator_fast for Item references
+*/
+
+class Item_iterator_ref_list: public Item_iterator
+{
+ List_iterator<Item*> list;
+public:
+ Item_iterator_ref_list(List_iterator<Item*> &arg_list):
+ list(arg_list) {}
+ void open() { list.rewind(); }
+ Item *next() { return *(list++); }
+ void close() {}
+};
+
+
+/**
+ Item iterator over Item interface for rows
+*/
+
+class Item_iterator_row: public Item_iterator
+{
+ Item *base_item;
+ uint current;
+public:
+ Item_iterator_row(Item *base) : base_item(base), current(0) {}
+ void open() { current= 0; }
+ Item *next()
+ {
+ if (current >= base_item->cols())
+ return NULL;
+ return base_item->element_index(current++);
+ }
+ void close() {}
+};
+
+
/**
An interface that is used to take an action when
the locking module notices that a table version has changed
@@ -310,11 +380,13 @@ struct system_variables
ulonglong max_heap_table_size;
ulonglong tmp_table_size;
ulonglong long_query_time;
+ ulonglong join_buff_space_limit;
ha_rows select_limit;
ha_rows max_join_size;
ulong auto_increment_increment, auto_increment_offset;
ulong bulk_insert_buff_size;
ulong join_buff_size;
+ ulong join_cache_level;
ulong max_allowed_packet;
ulong max_error_count;
ulong max_length_for_sort_data;
@@ -322,7 +394,6 @@ struct system_variables
ulong max_tmp_tables;
ulong max_insert_delayed_threads;
ulong min_examined_row_limit;
- ulong multi_range_count;
ulong myisam_repair_threads;
ulong myisam_sort_buff_size;
ulong myisam_stats_method;
@@ -336,13 +407,25 @@ struct system_variables
ulong optimizer_search_depth;
/* A bitmap for switching optimizations on/off */
ulong optimizer_switch;
+ /*
+ Controls use of Engine-MRR:
+ 0 - auto, based on cost
+ 1 - force MRR when the storage engine is capable of doing it
+ 2 - disable MRR.
+ */
+ ulong optimizer_use_mrr;
+
ulong preload_buff_size;
ulong profiling_history_size;
ulong query_cache_type;
ulong read_buff_size;
ulong read_rnd_buff_size;
+ ulong mrr_buff_size;
ulong div_precincrement;
ulong sortbuff_size;
+ /* Total size of all buffers used by the subselect_rowid_merge_engine. */
+ ulong rowid_merge_buff_size;
+ ulong thread_handling;
ulong tx_isolation;
ulong completion_type;
/* Determines which non-standard SQL behaviour should be enabled */
@@ -443,6 +526,13 @@ typedef struct system_status_var
ulong ha_read_prev_count;
ulong ha_read_rnd_count;
ulong ha_read_rnd_next_count;
+ /*
+ This number doesn't include calls to the default implementation and
+ calls made by range access. The intent is to count only calls made by
+ BatchedKeyAccess.
+ */
+ ulong ha_multi_range_read_init_count;
+
ulong ha_rollback_count;
ulong ha_update_count;
ulong ha_write_count;
@@ -468,8 +558,6 @@ typedef struct system_status_var
ulong select_range_count;
ulong select_range_check_count;
ulong select_scan_count;
- ulong rows_read;
- ulong rows_sent;
ulong long_query_count;
ulong filesort_merge_passes;
ulong filesort_range_count;
@@ -499,6 +587,8 @@ typedef struct system_status_var
ulonglong bytes_received;
ulonglong bytes_sent;
ulonglong binlog_bytes_written;
+ ulonglong rows_read;
+ ulonglong rows_sent;
double last_query_cost;
double cpu_time, busy_time;
} STATUS_VAR;
@@ -1470,6 +1560,14 @@ public:
/* 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;
#ifndef MYSQL_CLIENT
int binlog_setup_trx_data();
@@ -1846,7 +1944,7 @@ public:
bool slave_thread, one_shot_set;
/* tells if current statement should binlog row-based(1) or stmt-based(0) */
bool current_stmt_binlog_row_based;
- bool locked, some_tables_deleted;
+ bool some_tables_deleted;
bool last_cuted_field;
bool no_errors, password;
bool extra_port; /* If extra connection */
@@ -2861,11 +2959,23 @@ public:
*/
bool precomputed_group_by;
bool force_copy_fields;
+ /*
+ If TRUE, create_tmp_field called from create_tmp_table will convert
+ all BIT fields to 64-bit longs. This is a workaround the limitation
+ that MEMORY tables cannot index BIT columns.
+ */
+ bool bit_fields_as_long;
+ /*
+ Whether to create or postpone actual creation of this temporary table.
+ TRUE <=> create_tmp_table will create only the TABLE structure.
+ */
+ bool skip_create_table;
TMP_TABLE_PARAM()
:copy_field(0), group_parts(0),
group_length(0), group_null_parts(0), convert_blob_length(0),
- schema_table(0), precomputed_group_by(0), force_copy_fields(0)
+ schema_table(0), precomputed_group_by(0), force_copy_fields(0),
+ bit_fields_as_long(0), skip_create_table(0)
{}
~TMP_TABLE_PARAM()
{
@@ -2884,19 +2994,21 @@ public:
class select_union :public select_result_interceptor
{
+protected:
TMP_TABLE_PARAM tmp_table_param;
+ int write_err; /* Error code from the last send_data->ha_write_row call. */
public:
TABLE *table;
- select_union() :table(0) {}
+ select_union() :write_err(0),table(0) { tmp_table_param.init(); }
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items);
bool send_eof();
bool flush();
-
- bool create_result_table(THD *thd, List<Item> *column_types,
- bool is_distinct, ulonglong options,
- const char *alias);
+ void cleanup();
+ virtual bool create_result_table(THD *thd, List<Item> *column_types,
+ bool is_distinct, ulonglong options,
+ const char *alias, bool bit_fields_as_long);
};
/* Base subselect interface class */
@@ -2920,6 +3032,72 @@ public:
bool send_data(List<Item> &items);
};
+
+/*
+ This class specializes select_union to collect statistics about the
+ data stored in the temp table. Currently the class collects statistcs
+ about NULLs.
+*/
+
+class select_materialize_with_stats : public select_union
+{
+protected:
+ class Column_statistics
+ {
+ public:
+ /* 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;
+ /* The row number that contains the last NULL in a column. */
+ ha_rows max_null_row;
+ };
+
+ /* Array of statistics data per column. */
+ Column_statistics* col_stat;
+
+ /*
+ The number of columns in the biggest sub-row that consists of only
+ NULL values.
+ */
+ uint max_nulls_in_row;
+ /*
+ Count of rows writtent to the temp table. This is redundant as it is
+ already stored in handler::stats.records, however that one is relatively
+ expensive to compute (given we need that for evry row).
+ */
+ ha_rows count_rows;
+
+protected:
+ void reset();
+
+public:
+ select_materialize_with_stats() {}
+ virtual bool create_result_table(THD *thd, List<Item> *column_types,
+ bool is_distinct, ulonglong options,
+ const char *alias, bool bit_fields_as_long);
+ bool init_result_table(ulonglong select_options);
+ bool send_data(List<Item> &items);
+ void cleanup();
+ ha_rows get_null_count_of_col(uint idx)
+ {
+ DBUG_ASSERT(idx < table->s->fields);
+ return col_stat[idx].null_count;
+ }
+ ha_rows get_max_null_of_col(uint idx)
+ {
+ DBUG_ASSERT(idx < table->s->fields);
+ return col_stat[idx].max_null_row;
+ }
+ ha_rows get_min_null_of_col(uint idx)
+ {
+ DBUG_ASSERT(idx < table->s->fields);
+ return col_stat[idx].min_null_row;
+ }
+ uint get_max_nulls_in_row() { return max_nulls_in_row; }
+};
+
+
/* used in independent ALL/ANY optimisation */
class select_max_min_finder_subselect :public select_subselect
{
@@ -2947,6 +3125,67 @@ public:
bool send_data(List<Item> &items);
};
+
+
+
+/*
+ Optimizer and executor structure for the materialized semi-join info. This
+ structure contains
+ - The sj-materialization temporary table
+ - Members needed to make index lookup or a full scan of the temptable.
+*/
+class SJ_MATERIALIZATION_INFO : public Sql_alloc
+{
+public:
+ /* Optimal join sub-order */
+ struct st_position *positions;
+
+ uint tables; /* Number of tables in the sj-nest */
+
+ /* Expected #rows in the materialized table */
+ double rows;
+
+ /*
+ Cost to materialize - execute the sub-join and write rows into temp.table
+ */
+ COST_VECT materialization_cost;
+
+ /* Cost to make one lookup in the temptable */
+ COST_VECT lookup_cost;
+
+ /* Cost of scanning the materialized table */
+ COST_VECT scan_cost;
+
+ /* --- Execution structures ---------- */
+
+ /*
+ TRUE <=> This structure is used for execution. We don't necessarily pick
+ sj-materialization, so some of SJ_MATERIALIZATION_INFO structures are not
+ used by materialization
+ */
+ bool is_used;
+
+ bool materialized; /* TRUE <=> materialization already performed */
+ /*
+ TRUE - the temptable is read with full scan
+ FALSE - we use the temptable for index lookups
+ */
+ bool is_sj_scan;
+
+ /* The temptable and its related info */
+ TMP_TABLE_PARAM sjm_table_param;
+ List<Item> sjm_table_cols;
+ TABLE *table;
+
+ /* Structure used to make index lookups */
+ struct st_table_ref *tab_ref;
+ Item *in_equality; /* See create_subq_in_equalities() */
+
+ Item *join_cond; /* See comments in make_join_select() */
+ Copy_field *copy_field; /* Needed for SJ_Materialization scan */
+};
+
+
/* Structs used when sorting */
typedef struct st_sort_field {
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 77be6eaff34..308c49fc15c 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -719,7 +719,8 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags)
{
DBUG_ASSERT(table == 0);
if (create_result_table(unit->thd, unit->get_unit_column_types(),
- FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
+ FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "",
+ FALSE))
return TRUE;
materialized_cursor= new (&table->mem_root)
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 7aa48524b20..b5478287fda 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -20,6 +20,7 @@
#include <mysys_err.h>
#include "sp.h"
#include "events.h"
+#include "sql_handler.h"
#include <my_dir.h>
#include <m_ctype.h>
#include "log.h"
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 5564d628594..e2cb17090a1 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -23,6 +23,7 @@
#include "sql_select.h"
#include "sp_head.h"
#include "sql_trigger.h"
+#include "sql_handler.h"
/**
Implement DELETE SQL word.
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 782589f7d0f..1c1e518e9c9 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -168,7 +168,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
*/
if ((res= derived_result->create_result_table(thd, &unit->types, FALSE,
create_options,
- orig_table_list->alias)))
+ orig_table_list->alias,
+ FALSE)))
goto exit;
table= derived_result->table;
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
new file mode 100644
index 00000000000..50fd7c7ee4d
--- /dev/null
+++ b/sql/sql_expression_cache.cc
@@ -0,0 +1,277 @@
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+/*
+ Expression cache is used only for caching subqueries now, so its statistic
+ variables we call subquery_cache*.
+*/
+ulong subquery_cache_miss, subquery_cache_hit;
+
+Expression_cache_tmptable::Expression_cache_tmptable(THD *thd,
+ List<Item*> &dependants,
+ Item *value)
+ :cache_table(NULL), table_thd(thd), list(&dependants), val(value),
+ inited (0)
+{
+ DBUG_ENTER("Expression_cache_tmptable::Expression_cache_tmptable");
+ DBUG_VOID_RETURN;
+};
+
+
+/**
+ Field enumerator for TABLE::add_tmp_key
+
+ @param arg reference variable with current field number
+
+ @return field number
+*/
+
+static uint field_enumerator(uchar *arg)
+{
+ return ((uint*)arg)[0]++;
+}
+
+
+/**
+ Initialize temporary table and auxiliary structures for the expression
+ cache
+
+ @details
+ The function creates a temporary table for the expression cache, defines
+ the search index and initializes auxiliary search structures used to check
+ whether a given set of of values of the expression parameters is in some
+ cache entry.
+*/
+
+void Expression_cache_tmptable::init()
+{
+ List_iterator<Item*> li(*list);
+ Item_iterator_ref_list it(li);
+ Item **item;
+ uint field_counter;
+ DBUG_ENTER("Expression_cache_tmptable::init");
+ DBUG_ASSERT(!inited);
+ inited= TRUE;
+ cache_table= NULL;
+
+ while ((item= li++))
+ {
+ DBUG_ASSERT(item);
+ if (*item)
+ {
+ DBUG_ASSERT((*item)->fixed);
+ items.push_back((*item));
+ }
+ else
+ {
+ /*
+ This is possible when optimizer already executed this subquery and
+ optimized out the condition predicate.
+ */
+ li.remove();
+ }
+ }
+
+ if (list->elements == 0)
+ {
+ DBUG_PRINT("info", ("All parameters were removed by optimizer."));
+ DBUG_VOID_RETURN;
+ }
+
+ cache_table_param.init();
+ /* dependent items and result */
+ cache_table_param.field_count= list->elements + 1;
+ /* postpone table creation to index description */
+ cache_table_param.skip_create_table= 1;
+ cache_table= NULL;
+
+ items.push_front(val);
+
+ if (!(cache_table= create_tmp_table(table_thd, &cache_table_param,
+ items, (ORDER*) NULL,
+ FALSE, FALSE,
+ ((table_thd->options |
+ TMP_TABLE_ALL_COLUMNS) &
+ ~(OPTION_BIG_TABLES |
+ TMP_TABLE_FORCE_MYISAM)),
+ HA_POS_ERROR,
+ (char *)"subquery-cache-table")))
+ {
+ DBUG_PRINT("error", ("create_tmp_table failed, caching switched off"));
+ DBUG_VOID_RETURN;
+ }
+
+ if (cache_table->s->db_type() != heap_hton)
+ {
+ DBUG_PRINT("error", ("we need only heap table"));
+ goto error;
+ }
+
+ /* This list do not contain result field */
+ it.open();
+
+ field_counter=1;
+
+ if (cache_table->alloc_keys(1) ||
+ cache_table->add_tmp_key(0, items.elements - 1, &field_enumerator,
+ (uchar*)&field_counter, TRUE) ||
+ ref.tmp_table_index_lookup_init(table_thd, cache_table->key_info, it,
+ TRUE))
+ {
+ DBUG_PRINT("error", ("creating index failed"));
+ goto error;
+ }
+ cache_table->s->keys= 1;
+ cache_table->s->uniques= 1;
+ ref.null_rejecting= 1;
+ ref.disable_cache= FALSE;
+ ref.has_record= 0;
+ ref.use_count= 0;
+
+
+ if (open_tmp_table(cache_table))
+ {
+ DBUG_PRINT("error", ("Opening (creating) temporary table failed"));
+ goto error;
+ }
+
+ if (!(cached_result= new Item_field(cache_table->field[0])))
+ {
+ DBUG_PRINT("error", ("Creating Item_field failed"));
+ goto error;
+ }
+
+ DBUG_VOID_RETURN;
+
+error:
+ /* switch off cache */
+ free_tmp_table(table_thd, cache_table);
+ cache_table= NULL;
+ DBUG_VOID_RETURN;
+}
+
+
+Expression_cache_tmptable::~Expression_cache_tmptable()
+{
+ if (cache_table)
+ free_tmp_table(table_thd, cache_table);
+}
+
+
+/**
+ Check if a given set of parameters of the expression is in the cache
+
+ @param [out] value the expression value found in the cache if any
+
+ @details
+ For a given set of the parameters of the expression the function
+ checks whether it can be found in some entry of the cache. If so
+ the function returns the result of the expression extracted from
+ the cache.
+
+ @retval Expression_cache::HIT if the set of parameters is in the cache
+ @retval Expression_cache::MISS - otherwise
+*/
+
+Expression_cache::result Expression_cache_tmptable::check_value(Item **value)
+{
+ int res;
+ DBUG_ENTER("Expression_cache_tmptable::check_value");
+
+ /*
+ We defer cache initialization to get item references that are
+ used at the execution phase.
+ */
+ if (!inited)
+ init();
+
+ if (cache_table)
+ {
+ DBUG_PRINT("info", ("status: %u has_record %u",
+ (uint)cache_table->status, (uint)ref.has_record));
+ if ((res= join_read_key2(table_thd, NULL, cache_table, &ref)) == 1)
+ DBUG_RETURN(ERROR);
+ if (res)
+ {
+ subquery_cache_miss++;
+ DBUG_RETURN(MISS);
+ }
+
+ subquery_cache_hit++;
+ *value= cached_result;
+ DBUG_RETURN(Expression_cache::HIT);
+ }
+ DBUG_RETURN(Expression_cache::MISS);
+}
+
+
+/**
+ Put a new entry into the expression cache
+
+ @param value the result of the expression to be put into the cache
+
+ @details
+ The function evaluates 'value' and puts the result into the cache as the
+ result of the expression for the current set of parameters.
+
+ @retval FALSE OK
+ @retval TRUE Error
+*/
+
+my_bool Expression_cache_tmptable::put_value(Item *value)
+{
+ int error;
+ DBUG_ENTER("Expression_cache_tmptable::put_value");
+ DBUG_ASSERT(inited);
+
+ if (!cache_table)
+ {
+ DBUG_PRINT("info", ("No table so behave as we successfully put value"));
+ DBUG_RETURN(FALSE);
+ }
+
+ *(items.head_ref())= value;
+ fill_record(table_thd, cache_table->field, items, TRUE, TRUE);
+ if (table_thd->is_error())
+ goto err;;
+
+ if ((error= cache_table->file->ha_write_row(cache_table->record[0])))
+ {
+ /* create_myisam_from_heap will generate error if needed */
+ if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
+ create_internal_tmp_table_from_heap(table_thd, cache_table,
+ cache_table_param.start_recinfo,
+ &cache_table_param.recinfo,
+ error, 1))
+ goto err;
+ }
+ cache_table->status= 0; /* cache_table->record contains an existed record */
+ ref.has_record= TRUE; /* the same as above */
+ DBUG_PRINT("info", ("has_record: TRUE status: 0"));
+
+ DBUG_RETURN(FALSE);
+
+err:
+ free_tmp_table(table_thd, cache_table);
+ cache_table= NULL;
+ DBUG_RETURN(TRUE);
+}
+
+
+void Expression_cache_tmptable::print(String *str, enum_query_type query_type)
+{
+ List_iterator<Item*> li(*list);
+ Item **item;
+ bool is_first= TRUE;
+
+ str->append('<');
+ while ((item= li++))
+ {
+ if (!is_first)
+ str->append(',');
+ (*item)->print(str, query_type);
+ is_first= FALSE;
+ }
+ str->append('>');
+}
diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h
new file mode 100644
index 00000000000..88f71e0cf32
--- /dev/null
+++ b/sql/sql_expression_cache.h
@@ -0,0 +1,84 @@
+#ifndef SQL_EXPRESSION_CACHE_INCLUDED
+#define SQL_EXPRESSION_CACHE_INCLUDED
+
+#include "sql_select.h"
+
+/**
+ Interface for expression cache
+
+ @note
+ Parameters of an expression cache interface are set on the creation of the
+ cache. They are passed when a cache object of the implementation class is
+ constructed. That's why they are not visible in this interface.
+*/
+
+extern ulong subquery_cache_miss, subquery_cache_hit;
+
+class Expression_cache :public Sql_alloc
+{
+public:
+ enum result {ERROR, HIT, MISS};
+
+ Expression_cache(){};
+ virtual ~Expression_cache() {};
+ /**
+ Shall check the presence of expression value in the cache for a given
+ set of values of the expression parameters. Return the result of the
+ expression if it's found in the cache.
+ */
+ virtual result check_value(Item **value)= 0;
+ /**
+ Shall put the value of an expression for given set of its parameters
+ into the expression cache
+ */
+ virtual my_bool put_value(Item *value)= 0;
+
+ /**
+ Print cache parameters
+ */
+ virtual void print(String *str, enum_query_type query_type)= 0;
+};
+
+struct st_table_ref;
+struct st_join_table;
+class Item_field;
+
+
+/**
+ Implementation of expression cache over a temporary table
+*/
+
+class Expression_cache_tmptable :public Expression_cache
+{
+public:
+ Expression_cache_tmptable(THD *thd, List<Item*> &dependants, Item *value);
+ virtual ~Expression_cache_tmptable();
+ virtual result check_value(Item **value);
+ virtual my_bool put_value(Item *value);
+
+ void print(String *str, enum_query_type query_type);
+
+private:
+ void init();
+
+ /* tmp table parameters */
+ TMP_TABLE_PARAM cache_table_param;
+ /* temporary table to store this cache */
+ TABLE *cache_table;
+ /* Thread handle for the temporary table */
+ THD *table_thd;
+ /* TABLE_REF for index lookup */
+ struct st_table_ref ref;
+ /* Cached result */
+ Item_field *cached_result;
+ /* List of references to the parameters of the expression */
+ List<Item*> *list;
+ /* List of items */
+ List<Item> items;
+ /* Value Item example */
+ Item *val;
+ /* Set on if the object has been succesfully initialized with init() */
+ bool inited;
+};
+
+#endif /* SQL_EXPRESSION_CACHE_INCLUDED */
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 85b7e46a313..f0cc90f06a6 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -56,9 +56,13 @@
second container. When the table is flushed, the pointer is cleared.
*/
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
#include "mysql_priv.h"
#include "sql_select.h"
-#include <assert.h>
+#include "sql_handler.h"
#define HANDLER_TABLES_HASH_SIZE 120
@@ -66,6 +70,28 @@ static enum enum_ha_read_modes rkey_to_rnext[]=
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
/*
+ Set handler to state after create, but keep base information about
+ which table is used
+*/
+
+void SQL_HANDLER::reset()
+{
+ fields.empty();
+ arena.free_items();
+ free_root(&mem_root, MYF(0));
+ my_free(lock, MYF(MY_ALLOW_ZERO_PTR));
+ init();
+}
+
+/* Free all allocated data */
+
+SQL_HANDLER::~SQL_HANDLER()
+{
+ reset();
+ my_free(base_data, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+/*
Get hash key and hash key length.
SYNOPSIS
@@ -84,11 +110,11 @@ static enum enum_ha_read_modes rkey_to_rnext[]=
Pointer to the TABLE_LIST struct.
*/
-static char *mysql_ha_hash_get_key(TABLE_LIST *tables, size_t *key_len_p,
+static char *mysql_ha_hash_get_key(SQL_HANDLER *table, size_t *key_len,
my_bool first __attribute__((unused)))
{
- *key_len_p= strlen(tables->alias) + 1 ; /* include '\0' in comparisons */
- return tables->alias;
+ *key_len= table->handler_name.length + 1 ; /* include '\0' in comparisons */
+ return table->handler_name.str;
}
@@ -106,9 +132,9 @@ static char *mysql_ha_hash_get_key(TABLE_LIST *tables, size_t *key_len_p,
Nothing
*/
-static void mysql_ha_hash_free(TABLE_LIST *tables)
+static void mysql_ha_hash_free(SQL_HANDLER *table)
{
- my_free((char*) tables, MYF(0));
+ delete table;
}
/**
@@ -120,14 +146,21 @@ static void mysql_ha_hash_free(TABLE_LIST *tables)
@note Though this function takes a list of tables, only the first list entry
will be closed.
+ @mote handler_object is not deleted!
@note Broadcasts refresh if it closed a table with old version.
*/
-static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
+static void mysql_ha_close_table(SQL_HANDLER *handler,
bool is_locked)
{
+ THD *thd= handler->thd;
+ TABLE *table= handler->table;
TABLE **table_ptr;
+ /* check if table was already closed */
+ if (!table)
+ return;
+
/*
Though we could take the table pointer from hash_tables->table,
we must follow the thd->handler_tables chain anyway, as we need the
@@ -135,13 +168,18 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
for close_thread_table().
*/
for (table_ptr= &(thd->handler_tables);
- *table_ptr && (*table_ptr != tables->table);
+ *table_ptr && (*table_ptr != table);
table_ptr= &(*table_ptr)->next)
;
if (*table_ptr)
{
- (*table_ptr)->file->ha_index_or_rnd_end();
+ if (handler->lock)
+ {
+ // Mark it unlocked, like in reset_lock_data()
+ reset_lock_data(handler->lock, 1);
+ }
+ table->file->ha_index_or_rnd_end();
if (! is_locked)
VOID(pthread_mutex_lock(&LOCK_open));
if (close_thread_table(thd, table_ptr))
@@ -152,17 +190,15 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
if (! is_locked)
VOID(pthread_mutex_unlock(&LOCK_open));
}
- else if (tables->table)
+ else
{
/* Must be a temporary table */
- TABLE *table= tables->table;
table->file->ha_index_or_rnd_end();
table->query_id= thd->query_id;
table->open_by_handler= 0;
}
-
- /* Mark table as closed, ready for re-open if necessary. */
- tables->table= NULL;
+ my_free(handler->lock, MYF(MY_ALLOW_ZERO_PTR));
+ handler->init();
}
/*
@@ -178,7 +214,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
Though this function takes a list of tables, only the first list entry
will be opened.
'reopen' is set when a handler table is to be re-opened. In this case,
- 'tables' is the pointer to the hashed TABLE_LIST object which has been
+ 'tables' is the pointer to the hashed SQL_HANDLER object which has been
saved on the original open.
'reopen' is also used to suppress the sending of an 'ok' message.
@@ -187,17 +223,17 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
TRUE Error
*/
-bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
+bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
{
- TABLE_LIST *hash_tables = NULL;
- char *db, *name, *alias;
- uint dblen, namelen, aliaslen, counter;
+ SQL_HANDLER *sql_handler= 0;
+ uint counter;
int error;
- TABLE *backup_open_tables;
+ TABLE *table, *backup_open_tables, *write_lock_used;
+ Query_arena backup_arena;
DBUG_ENTER("mysql_ha_open");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d",
tables->db, tables->table_name, tables->alias,
- (int) reopen));
+ reopen != 0));
if (tables->schema_table)
{
@@ -210,7 +246,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
if (! hash_inited(&thd->handler_tables_hash))
{
/*
- HASH entries are of type TABLE_LIST.
+ HASH entries are of type SQL_HANDLER
*/
if (hash_init(&thd->handler_tables_hash, &my_charset_latin1,
HANDLER_TABLES_HASH_SIZE, 0, 0,
@@ -288,8 +324,10 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
if (error)
goto err;
+ table= tables->table;
+
/* There can be only one table in '*tables'. */
- if (! (tables->table->file->ha_table_flags() & HA_CAN_SQL_HANDLER))
+ if (! (table->file->ha_table_flags() & HA_CAN_SQL_HANDLER))
{
my_error(ER_ILLEGAL_HA, MYF(0), tables->alias);
goto err;
@@ -297,36 +335,69 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
if (! reopen)
{
- /* copy the TABLE_LIST struct */
- dblen= strlen(tables->db) + 1;
- namelen= strlen(tables->table_name) + 1;
- aliaslen= strlen(tables->alias) + 1;
- if (!(my_multi_malloc(MYF(MY_WME),
- &hash_tables, (uint) sizeof(*hash_tables),
- &db, (uint) dblen,
- &name, (uint) namelen,
- &alias, (uint) aliaslen,
+ /* copy data to sql_handler */
+ if (!(sql_handler= new SQL_HANDLER(thd)))
+ goto err;
+ init_alloc_root(&sql_handler->mem_root, 1024, 0);
+
+ sql_handler->table= table;
+ sql_handler->db.length= strlen(tables->db);
+ sql_handler->table_name.length= strlen(tables->table_name);
+ sql_handler->handler_name.length= strlen(tables->alias);
+
+ if (!(my_multi_malloc(MY_WME,
+ &sql_handler->db.str,
+ (uint) sql_handler->db.length + 1,
+ &sql_handler->table_name.str,
+ (uint) sql_handler->table_name.length + 1,
+ &sql_handler->handler_name.str,
+ (uint) sql_handler->handler_name.length + 1,
NullS)))
goto err;
- /* structure copy */
- *hash_tables= *tables;
- hash_tables->db= db;
- hash_tables->table_name= name;
- hash_tables->alias= alias;
- memcpy(hash_tables->db, tables->db, dblen);
- memcpy(hash_tables->table_name, tables->table_name, namelen);
- memcpy(hash_tables->alias, tables->alias, aliaslen);
+ sql_handler->base_data= sql_handler->db.str; // Free this
+ memcpy(sql_handler->db.str, tables->db, sql_handler->db.length +1);
+ memcpy(sql_handler->table_name.str, tables->table_name,
+ sql_handler->table_name.length+1);
+ memcpy(sql_handler->handler_name.str, tables->alias,
+ sql_handler->handler_name.length +1);
/* add to hash */
- if (my_hash_insert(&thd->handler_tables_hash, (uchar*) hash_tables))
+ if (my_hash_insert(&thd->handler_tables_hash, (uchar*) sql_handler))
goto err;
}
+ else
+ {
+ sql_handler= reopen;
+ sql_handler->reset();
+ }
+ sql_handler->table= table;
+
+ if (!(sql_handler->lock= get_lock_data(thd, &sql_handler->table, 1,
+ GET_LOCK_STORE_LOCKS,
+ &write_lock_used)))
+ goto err;
+
+ /* Get a list of all fields for send_fields */
+ thd->set_n_backup_active_arena(&sql_handler->arena, &backup_arena);
+ error= table->fill_item_list(&sql_handler->fields);
+ thd->restore_active_arena(&sql_handler->arena, &backup_arena);
+
+ if (error)
+ {
+ if (reopen)
+ sql_handler= 0;
+ goto err;
+ }
+
+ /* Always read all columns */
+ table->read_set= &table->s->all_set;
+ table->vcol_set= &table->s->all_set;
/*
If it's a temp table, don't reset table->query_id as the table is
being used by this handler. Otherwise, no meaning at all.
*/
- tables->table->open_by_handler= 1;
+ table->open_by_handler= 1;
if (! reopen)
my_ok(thd);
@@ -334,10 +405,13 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
DBUG_RETURN(FALSE);
err:
- if (hash_tables)
- my_free((char*) hash_tables, MYF(0));
+ delete sql_handler;
if (tables->table)
- mysql_ha_close_table(thd, tables, FALSE);
+ {
+ SQL_HANDLER tmp_sql_handler(thd);
+ tmp_sql_handler.table= tables->table;
+ mysql_ha_close_table(&tmp_sql_handler, FALSE);
+ }
DBUG_PRINT("exit",("ERROR"));
DBUG_RETURN(TRUE);
}
@@ -362,17 +436,17 @@ err:
bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
{
- TABLE_LIST *hash_tables;
+ SQL_HANDLER *handler;
DBUG_ENTER("mysql_ha_close");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias));
- if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
- (uchar*) tables->alias,
- strlen(tables->alias) + 1)))
+ if ((handler= (SQL_HANDLER*) hash_search(&thd->handler_tables_hash,
+ (uchar*) tables->alias,
+ strlen(tables->alias) + 1)))
{
- mysql_ha_close_table(thd, hash_tables, FALSE);
- hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
+ mysql_ha_close_table(handler, FALSE);
+ hash_delete(&thd->handler_tables_hash, (uchar*) handler);
}
else
{
@@ -387,6 +461,167 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
}
+/**
+ Finds an open HANDLER table.
+
+ @params name Name of handler to open
+
+ @return 0 failure
+ @return handler
+*/
+
+SQL_HANDLER *mysql_ha_find_handler(THD *thd, const char *name)
+{
+ SQL_HANDLER *handler;
+ if ((handler= (SQL_HANDLER*) hash_search(&thd->handler_tables_hash,
+ (uchar*) name,
+ strlen(name) + 1)))
+ {
+ DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' table: %p",
+ handler->db.str,
+ handler->table_name.str,
+ handler->handler_name.str, handler->table));
+ if (!handler->table)
+ {
+ /* The handler table has been closed. Re-open it. */
+ TABLE_LIST tmp;
+ tmp.init_one_table(handler->db.str, handler->table_name.str,
+ TL_READ);
+ tmp.alias= handler->handler_name.str;
+
+ if (mysql_ha_open(thd, &tmp, handler))
+ {
+ DBUG_PRINT("exit",("reopen failed"));
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ my_error(ER_UNKNOWN_TABLE, MYF(0), name, "HANDLER");
+ return 0;
+ }
+ return handler;
+}
+
+
+/**
+ Check that condition and key name are ok
+
+ @param handler
+ @param mode Read mode (RFIRST, RNEXT etc...)
+ @param keyname Key to use.
+ @param key_expr List of key column values
+ @param cond Where clause
+ @param in_prepare If we are in prepare phase (we can't evalute items yet)
+
+ @return 0 ok
+ @return 1 error
+
+ In ok, then values of used key and mode is stored in sql_handler
+*/
+
+static bool
+mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
+ enum enum_ha_read_modes mode, char *keyname,
+ List<Item> *key_expr,
+ Item *cond, bool in_prepare)
+{
+ THD *thd= handler->thd;
+ TABLE *table= handler->table;
+ if (cond)
+ {
+ /* This can only be true for temp tables */
+ if (table->query_id != thd->query_id)
+ cond->cleanup(); // File was reopened
+ if ((!cond->fixed &&
+ cond->fix_fields(thd, &cond)) || cond->check_cols(1))
+ return 1;
+ }
+
+ if (keyname)
+ {
+ /* Check if same as last keyname. If not, do a full lookup */
+ if (handler->keyno < 0 ||
+ my_strcasecmp(&my_charset_latin1,
+ keyname,
+ table->s->key_info[handler->keyno].name))
+ {
+ if ((handler->keyno= find_type(keyname, &table->s->keynames, 1+2)-1)<0)
+ {
+ my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname,
+ handler->handler_name);
+ return 1;
+ }
+ }
+
+ /* Check key parts */
+ if (mode == RKEY)
+ {
+ TABLE *table= handler->table;
+ KEY *keyinfo= table->key_info + handler->keyno;
+ KEY_PART_INFO *key_part= keyinfo->key_part;
+ List_iterator<Item> it_ke(*key_expr);
+ Item *item;
+ key_part_map keypart_map;
+ uint key_len;
+
+ if (key_expr->elements > keyinfo->key_parts)
+ {
+ my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts);
+ return 1;
+ }
+ for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++)
+ {
+ my_bitmap_map *old_map;
+ /* note that 'item' can be changed by fix_fields() call */
+ if ((!item->fixed &&
+ item->fix_fields(thd, it_ke.ref())) ||
+ (item= *it_ke.ref())->check_cols(1))
+ return 1;
+ if (item->used_tables() & ~(RAND_TABLE_BIT | PARAM_TABLE_BIT))
+ {
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");
+ return 1;
+ }
+ if (!in_prepare)
+ {
+ old_map= dbug_tmp_use_all_columns(table, table->write_set);
+ (void) item->save_in_field(key_part->field, 1);
+ dbug_tmp_restore_column_map(table->write_set, old_map);
+ }
+ key_len+= key_part->store_length;
+ keypart_map= (keypart_map << 1) | 1;
+ }
+ handler->keypart_map= keypart_map;
+ handler->key_len= key_len;
+ }
+ else
+ {
+ /*
+ Check if the same index involved.
+ We need to always do this check because we may not have yet
+ called the handler since the last keyno change.
+ */
+ if ((uint) handler->keyno != table->file->get_index())
+ {
+ if (mode == RNEXT)
+ mode= RFIRST;
+ else if (mode == RPREV)
+ mode= RLAST;
+ }
+ }
+ }
+ else if (table->file->inited != handler::RND)
+ {
+ /* Convert RNEXT to RFIRST if we haven't started row scan */
+ if (mode == RNEXT)
+ mode= RFIRST;
+ }
+ handler->mode= mode; // Store adjusted mode
+ return 0;
+}
+
/*
Read from a HANDLER table.
@@ -413,153 +648,77 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
enum ha_rkey_function ha_rkey_mode, Item *cond,
ha_rows select_limit_cnt, ha_rows offset_limit_cnt)
{
- TABLE_LIST *hash_tables;
- TABLE *table, *backup_open_tables;
- MYSQL_LOCK *lock;
+ SQL_HANDLER *handler;
+ TABLE *table;
List<Item> list;
Protocol *protocol= thd->protocol;
char buff[MAX_FIELD_WIDTH];
String buffer(buff, sizeof(buff), system_charset_info);
- int error, keyno= -1;
+ int error, keyno;
uint num_rows;
uchar *UNINIT_VAR(key);
uint UNINIT_VAR(key_len);
bool need_reopen;
+ List_iterator<Item> it;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias));
- thd->lex->select_lex.context.resolve_in_table_list_only(tables);
- list.push_front(new Item_field(&thd->lex->select_lex.context,
- NULL, NULL, "*"));
- List_iterator<Item> it(list);
- it++;
retry:
- if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
- (uchar*) tables->alias,
- strlen(tables->alias) + 1)))
+ if (!(handler= mysql_ha_find_handler(thd, tables->alias)))
+ goto err0;
+
+ table= handler->table;
+ tables->table= table; // This is used by fix_fields
+
+ /* save open_tables state */
+ if (handler->lock->lock_count > 0)
{
- table= hash_tables->table;
- DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' table: 0x%lx",
- hash_tables->db, hash_tables->table_name,
- hash_tables->alias, (long) table));
- if (!table)
+ bool lock_error;
+
+ handler->lock->locks[0]->type= handler->lock->locks[0]->org_type;
+ lock_error= mysql_lock_tables(thd, handler->lock, 0,
+ (MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN |
+ (handler->table->s->tmp_table ==
+ NO_TMP_TABLE ?
+ MYSQL_LOCK_NOT_TEMPORARY : 0)),
+ &need_reopen);
+ if (need_reopen)
{
- /*
- The handler table has been closed. Re-open it.
- */
- if (mysql_ha_open(thd, hash_tables, 1))
+ mysql_ha_close_table(handler, FALSE);
+ if (thd->stmt_arena->is_stmt_execute())
{
- DBUG_PRINT("exit",("reopen failed"));
+ /*
+ As we have already sent field list and types to the client, we can't
+ handle any changes in the table format for prepared statements.
+ Better to force a reprepare.
+ */
+ my_error(ER_NEED_REPREPARE, MYF(0));
goto err0;
}
- table= hash_tables->table;
- DBUG_PRINT("info",("re-opened '%s'.'%s' as '%s' tab %p",
- hash_tables->db, hash_tables->table_name,
- hash_tables->alias, table));
- }
-
-#if MYSQL_VERSION_ID < 40100
- if (*tables->db && strcmp(table->table_cache_key, tables->db))
- {
- DBUG_PRINT("info",("wrong db"));
- table= NULL;
+ /*
+ The lock might have been aborted, we need to manually reset
+ thd->some_tables_deleted because handler's tables are closed
+ in a non-standard way. Otherwise we might loop indefinitely.
+ */
+ thd->some_tables_deleted= 0;
+ goto retry;
}
-#endif
- }
- else
- table= NULL;
-
- if (!table)
- {
-#if MYSQL_VERSION_ID < 40100
- char buff[MAX_DBKEY_LENGTH];
- if (*tables->db)
- strxnmov(buff, sizeof(buff)-1, tables->db, ".", tables->table_name,
- NullS);
- else
- strncpy(buff, tables->alias, sizeof(buff));
- my_error(ER_UNKNOWN_TABLE, MYF(0), buff, "HANDLER");
-#else
- my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER");
-#endif
- goto err0;
- }
- tables->table=table;
-
- /* save open_tables state */
- backup_open_tables= thd->open_tables;
- /*
- mysql_lock_tables() needs thd->open_tables to be set correctly to
- be able to handle aborts properly. When the abort happens, it's
- safe to not protect thd->handler_tables because it won't close any
- tables.
- */
- thd->open_tables= thd->handler_tables;
-
- lock= mysql_lock_tables(thd, &tables->table, 1,
- MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &need_reopen);
-
- /* restore previous context */
- thd->open_tables= backup_open_tables;
-
- if (need_reopen)
- {
- mysql_ha_close_table(thd, hash_tables, FALSE);
- /*
- The lock might have been aborted, we need to manually reset
- thd->some_tables_deleted because handler's tables are closed
- in a non-standard way. Otherwise we might loop indefinitely.
- */
- thd->some_tables_deleted= 0;
- goto retry;
- }
- if (!lock)
- goto err0; // mysql_lock_tables() printed error message already
-
- // Always read all columns
- tables->table->read_set= &tables->table->s->all_set;
-
- if (cond)
- {
- if (table->query_id != thd->query_id)
- cond->cleanup(); // File was reopened
- if ((!cond->fixed &&
- cond->fix_fields(thd, &cond)) || cond->check_cols(1))
- goto err;
+ if (lock_error)
+ goto err0; // mysql_lock_tables() printed error message already
}
- if (keyname)
- {
- if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0)
- {
- my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
- goto err;
- }
- /* Check if the same index involved. */
- if ((uint) keyno != table->file->get_index())
- {
- if (mode == RNEXT)
- mode= RFIRST;
- else if (mode == RPREV)
- mode= RLAST;
- }
- }
- else if (table->file->inited != handler::RND)
- {
- /* Convert RNEXT to RFIRST if we haven't started row scan */
- if (mode == RNEXT)
- mode= RFIRST;
- }
-
- if (insert_fields(thd, &thd->lex->select_lex.context,
- tables->db, tables->alias, &it, 0))
+ if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 0))
goto err;
+ mode= handler->mode;
+ keyno= handler->keyno;
- protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
+ it.init(handler->fields);
+ protocol->send_fields(&handler->fields,
+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
/*
In ::external_lock InnoDB resets the fields which tell it that
@@ -584,9 +743,7 @@ retry:
error= table->file->ha_index_next(table->record[0]);
}
else
- {
error= table->file->ha_rnd_next(table->record[0]);
- }
break;
}
/* else fall through */
@@ -603,7 +760,7 @@ retry:
if (!(error= table->file->ha_rnd_init(1)))
error= table->file->ha_rnd_next(table->record[0]);
}
- mode=RNEXT;
+ mode= RNEXT;
break;
case RPREV:
DBUG_ASSERT(keyname != 0);
@@ -622,7 +779,7 @@ retry:
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno, 1);
error= table->file->ha_index_last(table->record[0]);
- mode=RPREV;
+ mode= RPREV;
break;
case RNEXT_SAME:
/* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */
@@ -632,44 +789,17 @@ retry:
case RKEY:
{
DBUG_ASSERT(keyname != 0);
- KEY *keyinfo=table->key_info+keyno;
- KEY_PART_INFO *key_part=keyinfo->key_part;
- if (key_expr->elements > keyinfo->key_parts)
- {
- my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts);
- goto err;
- }
- List_iterator<Item> it_ke(*key_expr);
- Item *item;
- key_part_map keypart_map;
- for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++)
- {
- my_bitmap_map *old_map;
- // 'item' can be changed by fix_fields() call
- if ((!item->fixed &&
- item->fix_fields(thd, it_ke.ref())) ||
- (item= *it_ke.ref())->check_cols(1))
- goto err;
- if (item->used_tables() & ~RAND_TABLE_BIT)
- {
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");
- goto err;
- }
- old_map= dbug_tmp_use_all_columns(table, table->write_set);
- (void) item->save_in_field(key_part->field, 1);
- dbug_tmp_restore_column_map(table->write_set, old_map);
- key_len+=key_part->store_length;
- keypart_map= (keypart_map << 1) | 1;
- }
- if (!(key= (uchar*) thd->calloc(ALIGN_SIZE(key_len))))
+ if (!(key= (uchar*) thd->calloc(ALIGN_SIZE(handler->key_len))))
goto err;
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno, 1);
- key_copy(key, table->record[0], table->key_info + keyno, key_len);
+ key_copy(key, table->record[0], table->key_info + keyno,
+ handler->key_len);
error= table->file->ha_index_read_map(table->record[0],
- key, keypart_map, ha_rkey_mode);
- mode=rkey_to_rnext[(int)ha_rkey_mode];
+ key, handler->keypart_map,
+ ha_rkey_mode);
+ mode= rkey_to_rnext[(int)ha_rkey_mode];
break;
}
default:
@@ -716,13 +846,13 @@ retry:
num_rows++;
}
ok:
- mysql_unlock_tables(thd,lock);
+ mysql_unlock_tables(thd, handler->lock, 0);
my_eof(thd);
DBUG_PRINT("exit",("OK"));
DBUG_RETURN(FALSE);
err:
- mysql_unlock_tables(thd,lock);
+ mysql_unlock_tables(thd, handler->lock, 0);
err0:
DBUG_PRINT("exit",("ERROR"));
DBUG_RETURN(TRUE);
@@ -730,6 +860,28 @@ err0:
/**
+ Prepare for handler read
+
+ For parameters, see mysql_ha_read()
+*/
+
+SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables,
+ enum enum_ha_read_modes mode, char *keyname,
+ List<Item> *key_expr, Item *cond)
+{
+ SQL_HANDLER *handler;
+ DBUG_ENTER("mysql_ha_read_prepare");
+ if (!(handler= mysql_ha_find_handler(thd, tables->alias)))
+ DBUG_RETURN(0);
+ tables->table= handler->table; // This is used by fix_fields
+ if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1))
+ DBUG_RETURN(0);
+ DBUG_RETURN(handler);
+}
+
+
+
+/**
Scan the handler tables hash for matching tables.
@param thd Thread identifier.
@@ -740,30 +892,32 @@ err0:
table was matched.
*/
-static TABLE_LIST *mysql_ha_find(THD *thd, TABLE_LIST *tables)
+static SQL_HANDLER *mysql_ha_find_match(THD *thd, TABLE_LIST *tables)
{
- TABLE_LIST *hash_tables, *head= NULL, *first= tables;
- DBUG_ENTER("mysql_ha_find");
+ SQL_HANDLER *hash_tables, *head= NULL;
+ TABLE_LIST *first= tables;
+ DBUG_ENTER("mysql_ha_find_match");
/* search for all handlers with matching table names */
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
{
- hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
+ hash_tables= (SQL_HANDLER*) hash_element(&thd->handler_tables_hash, i);
+
for (tables= first; tables; tables= tables->next_local)
{
if ((! *tables->db ||
- ! my_strcasecmp(&my_charset_latin1, hash_tables->db, tables->db)) &&
- ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name,
+ ! my_strcasecmp(&my_charset_latin1, hash_tables->db.str,
+ tables->db)) &&
+ ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name.str,
tables->table_name))
+ {
+ /* Link into hash_tables list */
+ hash_tables->next= head;
+ head= hash_tables;
break;
- }
- if (tables)
- {
- hash_tables->next_local= head;
- head= hash_tables;
+ }
}
}
-
DBUG_RETURN(head);
}
@@ -780,18 +934,18 @@ static TABLE_LIST *mysql_ha_find(THD *thd, TABLE_LIST *tables)
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables, bool is_locked)
{
- TABLE_LIST *hash_tables, *next;
+ SQL_HANDLER *hash_tables, *next;
DBUG_ENTER("mysql_ha_rm_tables");
DBUG_ASSERT(tables);
- hash_tables= mysql_ha_find(thd, tables);
+ hash_tables= mysql_ha_find_match(thd, tables);
while (hash_tables)
{
- next= hash_tables->next_local;
+ next= hash_tables->next;
if (hash_tables->table)
- mysql_ha_close_table(thd, hash_tables, is_locked);
+ mysql_ha_close_table(hash_tables, is_locked);
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
hash_tables= next;
}
@@ -811,16 +965,16 @@ void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables, bool is_locked)
void mysql_ha_flush(THD *thd)
{
- TABLE_LIST *hash_tables;
+ SQL_HANDLER *hash_tables;
DBUG_ENTER("mysql_ha_flush");
safe_mutex_assert_owner(&LOCK_open);
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
{
- hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
+ hash_tables= (SQL_HANDLER*) hash_element(&thd->handler_tables_hash, i);
if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock())
- mysql_ha_close_table(thd, hash_tables, TRUE);
+ mysql_ha_close_table(hash_tables, TRUE);
}
DBUG_VOID_RETURN;
@@ -837,14 +991,14 @@ void mysql_ha_flush(THD *thd)
void mysql_ha_cleanup(THD *thd)
{
- TABLE_LIST *hash_tables;
+ SQL_HANDLER *hash_tables;
DBUG_ENTER("mysql_ha_cleanup");
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
{
- hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
+ hash_tables= (SQL_HANDLER*) hash_element(&thd->handler_tables_hash, i);
if (hash_tables->table)
- mysql_ha_close_table(thd, hash_tables, FALSE);
+ mysql_ha_close_table(hash_tables, FALSE);
}
hash_free(&thd->handler_tables_hash);
diff --git a/sql/sql_handler.h b/sql/sql_handler.h
new file mode 100644
index 00000000000..54e72e9f50e
--- /dev/null
+++ b/sql/sql_handler.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2010 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 */
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+/* Open handlers are stored here */
+
+class SQL_HANDLER {
+public:
+ TABLE *table;
+ List<Item> fields; /* Fields, set on open */
+ THD *thd;
+ LEX_STRING handler_name;
+ LEX_STRING db;
+ LEX_STRING table_name;
+ MEM_ROOT mem_root;
+ MYSQL_LOCK *lock;
+
+ key_part_map keypart_map;
+ int keyno; /* Used key */
+ uint key_len;
+ enum enum_ha_read_modes mode;
+
+ /* This is only used when deleting many handler objects */
+ SQL_HANDLER *next;
+
+ Query_arena arena;
+ char *base_data;
+ SQL_HANDLER(THD *thd_arg) :
+ thd(thd_arg), arena(&mem_root, Query_arena::INITIALIZED)
+ { init(); clear_alloc_root(&mem_root); base_data= 0; }
+ void init() { keyno= -1; table= 0; lock= 0; }
+ void reset();
+
+ ~SQL_HANDLER();
+};
+
+bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen);
+bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
+bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
+ List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
+void mysql_ha_flush(THD *thd);
+void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables, bool is_locked);
+void mysql_ha_cleanup(THD *thd);
+
+SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables,
+ enum enum_ha_read_modes mode, char *keyname,
+ List<Item> *key_expr, Item *cond);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 72ca7310ee1..adc82d791b6 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -622,8 +622,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
/*
We can't write-delayed into a table locked with LOCK TABLES:
this will lead to a deadlock, since the delayed thread will
- never be able to get a lock on the table. QQQ: why not
- upgrade the lock here instead?
+ never be able to get a lock on the table.
*/
if (table_list->lock_type == TL_WRITE_DELAYED && thd->locked_tables &&
find_locked_table(thd, table_list->db, table_list->table_name))
@@ -808,7 +807,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
be overwritten by fill_record() anyway (and fill_record() does not
use default values in this case).
*/
- table->record[0][0]= share->default_values[0];
+#ifdef HAVE_valgrind
+ if (table->file->ha_table_flags() && HA_RECORD_MUST_BE_CLEAN_ON_WRITE)
+ restore_record(table,s->default_values); // Get empty record
+ else
+#endif
+ table->record[0][0]= share->default_values[0];
/* Fix undefined null_bits. */
if (share->null_bytes > 1 && share->last_null_bit_pos)
@@ -2072,6 +2076,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
TABLE *copy;
TABLE_SHARE *share;
uchar *bitmap;
+ char *copy_tmp;
DBUG_ENTER("Delayed_insert::get_local_table");
/* First request insert thread to get a lock */
@@ -2104,14 +2109,15 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
the other record buffers and alignment are unnecessary.
*/
thd_proc_info(client_thd, "allocating local table");
- copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
- (share->fields+1)*sizeof(Field**)+
- share->reclength +
- share->column_bitmap_size*3);
- if (!copy)
+ copy_tmp= (char*) client_thd->alloc(sizeof(*copy)+
+ (share->fields+1)*sizeof(Field**)+
+ share->reclength +
+ share->column_bitmap_size*3);
+ if (!copy_tmp)
goto error;
/* Copy the TABLE object. */
+ copy= new (copy_tmp) TABLE;
*copy= *table;
/* We don't need to change the file handler here */
/* Assign the pointers for the field pointers array and the record. */
@@ -3500,7 +3506,7 @@ int select_create::write_to_binlog(bool is_trans, int errcode)
Avoid to use thd->binlog_query() twice, otherwise it will print the unsafe
warning twice.
*/
- Query_log_event ev(thd, query.c_ptr_safe(), query.length(), is_trans,
+ Query_log_event ev(thd, query.ptr(), query.length(), is_trans,
FALSE, errcode);
return mysql_bin_log.write(&ev);
}
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
new file mode 100644
index 00000000000..01635c56585
--- /dev/null
+++ b/sql/sql_join_cache.cc
@@ -0,0 +1,4449 @@
+/* Copyright (C) 2000-2006 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ @brief
+ join cache optimizations
+
+ @defgroup Query_Optimizer Query Optimizer
+ @{
+*/
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+#include "opt_subselect.h"
+
+#define NO_MORE_RECORDS_IN_BUFFER (uint)(-1)
+
+
+/*****************************************************************************
+ * Join cache module
+******************************************************************************/
+
+/*
+ Fill in the descriptor of a flag field associated with a join cache
+
+ SYNOPSIS
+ add_field_flag_to_join_cache()
+ str position in a record buffer to copy the field from/to
+ length length of the field
+ field IN/OUT pointer to the field descriptor to fill in
+
+ DESCRIPTION
+ The function fill in the descriptor of a cache flag field to which
+ the parameter 'field' points to. The function uses the first two
+ parameters to set the position in the record buffer from/to which
+ the field value is to be copied and the length of the copied fragment.
+ Before returning the result the function increments the value of
+ *field by 1.
+ The function ignores the fields 'blob_length' and 'ofset' of the
+ descriptor.
+
+ RETURN VALUE
+ the length of the field
+*/
+
+static
+uint add_flag_field_to_join_cache(uchar *str, uint length, CACHE_FIELD **field)
+{
+ CACHE_FIELD *copy= *field;
+ copy->str= str;
+ copy->length= length;
+ copy->type= 0;
+ copy->field= 0;
+ copy->referenced_field_no= 0;
+ (*field)++;
+ return length;
+}
+
+
+/*
+ Fill in the descriptors of table data fields associated with a join cache
+
+ SYNOPSIS
+ add_table_data_fields_to_join_cache()
+ tab descriptors of fields from this table are to be filled
+ field_set descriptors for only these fields are to be created
+ field_cnt IN/OUT counter of data fields
+ descr IN/OUT pointer to the first descriptor to be filled
+ field_ptr_cnt IN/OUT counter of pointers to the data fields
+ descr_ptr IN/OUT pointer to the first pointer to blob descriptors
+
+ DESCRIPTION
+ The function fills in the descriptors of cache data fields from the table
+ 'tab'. The descriptors are filled only for the fields marked in the
+ bitmap 'field_set'.
+ The function fills the descriptors starting from the position pointed
+ by 'descr'. If an added field is of a BLOB type then a pointer to the
+ its descriptor is added to the array descr_ptr.
+ At the return 'descr' points to the position after the last added
+ descriptor while 'descr_ptr' points to the position right after the
+ last added pointer.
+
+ RETURN VALUE
+ the total length of the added fields
+*/
+
+static
+uint add_table_data_fields_to_join_cache(JOIN_TAB *tab,
+ MY_BITMAP *field_set,
+ uint *field_cnt,
+ CACHE_FIELD **descr,
+ uint *field_ptr_cnt,
+ CACHE_FIELD ***descr_ptr)
+{
+ Field **fld_ptr;
+ uint len= 0;
+ CACHE_FIELD *copy= *descr;
+ CACHE_FIELD **copy_ptr= *descr_ptr;
+ uint used_fields= bitmap_bits_set(field_set);
+ for (fld_ptr= tab->table->field; used_fields; fld_ptr++)
+ {
+ if (bitmap_is_set(field_set, (*fld_ptr)->field_index))
+ {
+ len+= (*fld_ptr)->fill_cache_field(copy);
+ if (copy->type == CACHE_BLOB)
+ {
+ *copy_ptr= copy;
+ copy_ptr++;
+ (*field_ptr_cnt)++;
+ }
+ copy->field= *fld_ptr;
+ copy->referenced_field_no= 0;
+ copy++;
+ (*field_cnt)++;
+ used_fields--;
+ }
+ }
+ *descr= copy;
+ *descr_ptr= copy_ptr;
+ return len;
+}
+
+/*
+ Get the next table whose records are stored in the join buffer of this cache
+
+ SYNOPSIS
+ get_next_table()
+ tab the table for which the next table is to be returned
+
+ DESCRIPTION
+ For a given table whose records are stored in this cache the function
+ returns the next such table if there is any.
+ The function takes into account that the tables whose records are
+ are stored in the same cache now can interleave with tables from
+ materialized semijoin subqueries.
+
+ TODO
+ This function should be modified/simplified after the new code for
+ materialized semijoins is merged.
+
+ RETURN
+ The next join table whose records are stored in the buffer of this cache
+ if such table exists, 0 - otherwise
+*/
+
+JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab)
+{
+
+ if (++tab == join_tab)
+ return NULL;
+ if (join_tab->first_sjm_sibling)
+ return tab;
+ uint i= tab-join->join_tab;
+ while (sj_is_materialize_strategy(join->best_positions[i].sj_strategy) &&
+ i < join->tables)
+ i+= join->best_positions[i].n_sj_tables;
+ return join->join_tab+i < join_tab ? join->join_tab+i : NULL;
+}
+
+
+/*
+ Determine different counters of fields associated with a record in the cache
+
+ SYNOPSIS
+ calc_record_fields()
+
+ DESCRIPTION
+ The function counts the number of total fields stored in a record
+ of the cache and saves this number in the 'fields' member. It also
+ determines the number of flag fields and the number of blobs.
+ The function sets 'with_match_flag' on if 'join_tab' needs a match flag
+ i.e. if it is the first inner table of an outer join or a semi-join.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::calc_record_fields()
+{
+ JOIN_TAB *tab = prev_cache ? prev_cache->join_tab :
+ (join_tab->first_sjm_sibling ?
+ join_tab->first_sjm_sibling :
+ join->join_tab+join->const_tables);
+ tables= join_tab-tab;
+
+ fields= 0;
+ blobs= 0;
+ flag_fields= 0;
+ data_field_count= 0;
+ data_field_ptr_count= 0;
+ referenced_fields= 0;
+
+ for ( ; tab ; tab= get_next_table(tab))
+ {
+ tab->calc_used_field_length(FALSE);
+ flag_fields+= test(tab->used_null_fields || tab->used_uneven_bit_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++;
+ fields+= flag_fields;
+}
+
+
+/*
+ Collect information on join key arguments
+
+ SYNOPSIS
+ collect_info_on_key_args()
+
+ DESCRIPTION
+ The function traverses the ref expressions that are used to access the
+ joined table join_tab. For each table 'tab' whose fields are to be stored
+ in the join buffer of the cache the function finds the fields from 'tab'
+ that occur in the ref expressions and marks these fields in the bitmap
+ tab->table->tmp_set. The function counts the number of them stored
+ in this cache and the total number of them stored in the previous caches
+ and saves the results of the counting in 'local_key_arg_fields' and 'external_key_arg_fields' respectively.
+
+ NOTES
+ The function does not do anything if no key is used to join the records
+ from join_tab.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::collect_info_on_key_args()
+{
+ JOIN_TAB *tab;
+ JOIN_CACHE *cache;
+ local_key_arg_fields= 0;
+ external_key_arg_fields= 0;
+
+ if (!is_key_access())
+ return;
+
+ TABLE_REF *ref= &join_tab->ref;
+ cache= this;
+ do
+ {
+ for (tab= cache->join_tab-cache->tables; tab ;
+ tab= cache->get_next_table(tab))
+ {
+ uint key_args;
+ bitmap_clear_all(&tab->table->tmp_set);
+ for (uint i= 0; i < ref->key_parts; i++)
+ {
+ Item *ref_item= ref->items[i];
+ if (!(tab->table->map & ref_item->used_tables()))
+ continue;
+ ref_item->walk(&Item::add_field_to_set_processor, 1,
+ (uchar *) tab->table);
+ }
+ if ((key_args= bitmap_bits_set(&tab->table->tmp_set)))
+ {
+ if (cache == this)
+ local_key_arg_fields+= key_args;
+ else
+ external_key_arg_fields+= key_args;
+ }
+ }
+ cache= cache->prev_cache;
+ }
+ while (cache);
+
+ return;
+}
+
+
+/*
+ Allocate memory for descriptors and pointers to them associated with the cache
+
+ SYNOPSIS
+ alloc_fields()
+
+ DESCRIPTION
+ The function allocates memory for the array of fields descriptors
+ and the array of pointers to the field descriptors used to copy
+ join record data from record buffers into the join buffer and
+ backward. Some pointers refer to the field descriptor associated
+ with previous caches. They are placed at the beginning of the array
+ of pointers and its total number is stored in external_key_arg_fields.
+ The pointer of the first array is assigned to field_descr and the number
+ of the elements in it is precalculated by the function calc_record_fields.
+ The allocated arrays are adjacent.
+
+ NOTES
+ The memory is allocated in join->thd->memroot
+
+ RETURN VALUE
+ pointer to the first array
+*/
+
+int JOIN_CACHE::alloc_fields()
+{
+ uint ptr_cnt= external_key_arg_fields+blobs+1;
+ uint fields_size= sizeof(CACHE_FIELD)*fields;
+ field_descr= (CACHE_FIELD*) sql_alloc(fields_size +
+ sizeof(CACHE_FIELD*)*ptr_cnt);
+ blob_ptr= (CACHE_FIELD **) ((uchar *) field_descr + fields_size);
+ return (field_descr == NULL);
+}
+
+
+/*
+ Create descriptors of the record flag fields stored in the join buffer
+
+ SYNOPSIS
+ create_flag_fields()
+
+ DESCRIPTION
+ The function creates descriptors of the record flag fields stored
+ in the join buffer. These are descriptors for:
+ - an optional match flag field,
+ - table null bitmap fields,
+ - table null row fields.
+ The match flag field is created when 'join_tab' is the first inner
+ table of an outer join our a semi-join. A null bitmap field is
+ created for any table whose fields are to be stored in the join
+ buffer if at least one of these fields is nullable or is a BIT field
+ whose bits are partially stored with null bits. A null row flag
+ is created for any table assigned to the cache if it is an inner
+ table of an outer join.
+ The descriptor for flag fields are placed one after another at the
+ beginning of the array of field descriptors 'field_descr' that
+ contains 'fields' elements. If there is a match flag field the
+ descriptor for it is always first in the sequence of flag fields.
+ The descriptors for other flag fields can follow in an arbitrary
+ order.
+ The flag field values follow in a record stored in the join buffer
+ in the same order as field descriptors, with the match flag always
+ following first.
+ The function sets the value of 'flag_fields' to the total number
+ of the descriptors created for the flag fields.
+ The function sets the value of 'length' to the total length of the
+ flag fields.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::create_flag_fields()
+{
+ CACHE_FIELD *copy;
+ JOIN_TAB *tab;
+
+ copy= field_descr;
+
+ length=0;
+
+ /* If there is a match flag the first field is always used for this flag */
+ if (with_match_flag)
+ length+= add_flag_field_to_join_cache((uchar*) &join_tab->found,
+ sizeof(join_tab->found),
+ &copy);
+
+ /* Create fields for all null bitmaps and null row flags that are needed */
+ for (tab= join_tab-tables; tab; tab= get_next_table(tab))
+ {
+ TABLE *table= tab->table;
+
+ /* Create a field for the null bitmap from table if needed */
+ if (tab->used_null_fields || tab->used_uneven_bit_fields)
+ length+= add_flag_field_to_join_cache(table->null_flags,
+ table->s->null_bytes,
+ &copy);
+
+ /* Create table for the null row flag if needed */
+ if (table->maybe_null)
+ length+= add_flag_field_to_join_cache((uchar*) &table->null_row,
+ sizeof(table->null_row),
+ &copy);
+ }
+
+ /* Theoretically the new value of flag_fields can be less than the old one */
+ flag_fields= copy-field_descr;
+}
+
+
+/*
+ Create descriptors of the fields used to build access keys to the joined table
+
+ SYNOPSIS
+ create_key_arg_fields()
+
+ DESCRIPTION
+ The function creates descriptors of the record fields stored in the join
+ buffer that are used to build access keys to the joined table. These
+ fields are put into the buffer ahead of other records fields stored in
+ the buffer. Such placement helps to optimize construction of access keys.
+ For each field that is used to build access keys to the joined table but
+ is stored in some other join cache buffer the function saves a pointer
+ to the the field descriptor. The array of such pointers are placed in the
+ the join cache structure just before the array of pointers to the
+ blob fields blob_ptr.
+ Any field stored in a join cache buffer that is used to construct keys
+ to access tables associated with other join caches is called a referenced
+ field. It receives a unique number that is saved by the function in the
+ member 'referenced_field_no' of the CACHE_FIELD descriptor for the field.
+ This number is used as index to the array of offsets to the referenced
+ fields that are saved and put in the join cache buffer after all record
+ fields.
+ The function also finds out whether that the keys to access join_tab
+ can be considered as embedded and, if so, sets the flag 'use_emb_key' in
+ this join cache appropriately.
+
+ NOTES.
+ When a key to access the joined table 'join_tab' is constructed the array
+ of pointers to the field descriptors for the external fields is looked
+ through. For each of this pointers we find out in what previous key cache
+ the referenced field is stored. The value of 'referenced_field_no'
+ provides us with the index into the array of offsets for referenced
+ fields stored in the join cache. The offset read by the the index allows
+ us to read the field without reading all other fields of the record
+ stored the join cache buffer. This optimizes the construction of keys
+ to access 'join_tab' when some key arguments are stored in the previous
+ join caches.
+
+ NOTES
+ The function does not do anything if no key is used to join the records
+ from join_tab.
+
+ RETURN VALUE
+ none
+*/
+void JOIN_CACHE::create_key_arg_fields()
+{
+ JOIN_TAB *tab;
+ JOIN_CACHE *cache;
+
+ if (!is_key_access())
+ return;
+
+ /*
+ Save pointers to the cache fields in previous caches
+ that are used to build keys for this key access.
+ */
+ cache= this;
+ uint ext_key_arg_cnt= external_key_arg_fields;
+ CACHE_FIELD *copy;
+ CACHE_FIELD **copy_ptr= blob_ptr;
+ while (ext_key_arg_cnt)
+ {
+ cache= cache->prev_cache;
+ for (tab= cache->join_tab-cache->tables; tab;
+ tab= cache->get_next_table(tab))
+ {
+ CACHE_FIELD *copy_end;
+ MY_BITMAP *key_read_set= &tab->table->tmp_set;
+ /* key_read_set contains the bitmap of tab's fields referenced by ref */
+ if (bitmap_is_clear_all(key_read_set))
+ continue;
+ copy_end= cache->field_descr+cache->fields;
+ for (copy= cache->field_descr+cache->flag_fields; copy < copy_end; copy++)
+ {
+ /*
+ (1) - when we store rowids for DuplicateWeedout, they have
+ copy->field==NULL
+ */
+ if (copy->field && // (1)
+ copy->field->table == tab->table &&
+ bitmap_is_set(key_read_set, copy->field->field_index))
+ {
+ *copy_ptr++= copy;
+ ext_key_arg_cnt--;
+ if (!copy->referenced_field_no)
+ {
+ /*
+ Register the referenced field 'copy':
+ - set the offset number in copy->referenced_field_no,
+ - adjust the value of the flag 'with_length',
+ - adjust the values of 'pack_length' and
+ of 'pack_length_with_blob_ptrs'.
+ */
+ copy->referenced_field_no= ++cache->referenced_fields;
+ if (!cache->with_length)
+ {
+ cache->with_length= TRUE;
+ uint sz= cache->get_size_of_rec_length();
+ cache->base_prefix_length+= sz;
+ cache->pack_length+= sz;
+ cache->pack_length_with_blob_ptrs+= sz;
+ }
+ cache->pack_length+= cache->get_size_of_fld_offset();
+ cache->pack_length_with_blob_ptrs+= cache->get_size_of_fld_offset();
+ }
+ }
+ }
+ }
+ }
+ /* After this 'blob_ptr' shall not be be changed */
+ blob_ptr= copy_ptr;
+
+ /* Now create local fields that are used to build ref for this key access */
+ copy= field_descr+flag_fields;
+ for (tab= join_tab-tables; tab; tab= get_next_table(tab))
+ {
+ length+= add_table_data_fields_to_join_cache(tab, &tab->table->tmp_set,
+ &data_field_count, &copy,
+ &data_field_ptr_count,
+ &copy_ptr);
+ }
+
+ use_emb_key= check_emb_key_usage();
+
+ return;
+}
+
+
+/*
+ Create descriptors of all remaining data fields stored in the join buffer
+
+ SYNOPSIS
+ create_remaining_fields()
+
+ DESCRIPTION
+ The function creates descriptors for all remaining data fields of a
+ record from the join buffer. If the value returned by is_key_access() is
+ false the function creates fields for all read record fields that
+ comprise the partial join record joined with join_tab. Otherwise,
+ for each table tab, the set of the read fields for which the descriptors
+ have to be added is determined as the difference between all read fields
+ and and those for which the descriptors have been already created.
+ The latter are supposed to be marked in the bitmap tab->table->tmp_set.
+ The function increases the value of 'length' to the the total length of
+ the added fields.
+
+ NOTES
+ If is_key_access() returns true the function modifies the value of
+ tab->table->tmp_set for a each table whose fields are stored in the cache.
+ The function calls the method Field::fill_cache_field to figure out
+ the type of the cache field and the maximal length of its representation
+ in the join buffer. If this is a blob field then additionally a pointer
+ to this field is added as an element of the array blob_ptr. For a blob
+ field only the size of the length of the blob data is taken into account.
+ It is assumed that 'data_field_count' contains the number of descriptors
+ for data fields that have been already created and 'data_field_ptr_count'
+ contains the number of the pointers to such descriptors having been
+ stored up to the moment.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE:: create_remaining_fields()
+{
+ JOIN_TAB *tab;
+ bool all_read_fields= !is_key_access();
+ CACHE_FIELD *copy= field_descr+flag_fields+data_field_count;
+ CACHE_FIELD **copy_ptr= blob_ptr+data_field_ptr_count;
+
+ for (tab= join_tab-tables; tab; tab= get_next_table(tab))
+ {
+ MY_BITMAP *rem_field_set;
+ TABLE *table= tab->table;
+
+ if (all_read_fields)
+ rem_field_set= table->read_set;
+ else
+ {
+ bitmap_invert(&table->tmp_set);
+ bitmap_intersect(&table->tmp_set, table->read_set);
+ rem_field_set= &table->tmp_set;
+ }
+
+ length+= add_table_data_fields_to_join_cache(tab, rem_field_set,
+ &data_field_count, &copy,
+ &data_field_ptr_count,
+ &copy_ptr);
+
+ /* SemiJoinDuplicateElimination: allocate space for rowid if needed */
+ if (tab->keep_current_rowid)
+ {
+ copy->str= table->file->ref;
+ copy->length= table->file->ref_length;
+ copy->type= 0;
+ copy->field= 0;
+ copy->referenced_field_no= 0;
+ length+= copy->length;
+ data_field_count++;
+ copy++;
+ }
+ }
+}
+
+
+
+/*
+ Calculate and set all cache constants
+
+ SYNOPSIS
+ set_constants()
+
+ DESCRIPTION
+ The function calculates and set all precomputed constants that are used
+ when writing records into the join buffer and reading them from it.
+ It calculates the size of offsets of a record within the join buffer
+ and of a field within a record. It also calculates the number of bytes
+ used to store record lengths.
+ The function also calculates the maximal length of the representation
+ of record in the cache excluding blob_data. This value is used when
+ making a dicision whether more records should be added into the join
+ buffer or not.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::set_constants()
+{
+ /*
+ Any record from a BKA cache is prepended with the record length.
+ We use the record length when reading the buffer and building key values
+ for each record. The length allows us not to read the fields that are
+ not needed for keys.
+ If a record has match flag it also may be skipped when the match flag
+ is on. It happens if the cache is used for a semi-join operation or
+ for outer join when the 'not exist' optimization can be applied.
+ If some of the fields are referenced from other caches then
+ the record length allows us to easily reach the saved offsets for
+ these fields since the offsets are stored at the very end of the record.
+ However at this moment we don't know whether we have referenced fields for
+ the cache or not. Later when a referenced field is registered for the cache
+ we adjust the value of the flag 'with_length'.
+ */
+ with_length= is_key_access() ||
+ join_tab->is_inner_table_of_semi_join_with_first_match() ||
+ join_tab->is_inner_table_of_outer_join();
+ /*
+ At this moment we don't know yet the value of 'referenced_fields',
+ but in any case it can't be greater than the value of 'fields'.
+ */
+ uint len= length + fields*sizeof(uint)+blobs*sizeof(uchar *) +
+ (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) +
+ sizeof(ulong);
+ buff_size= max(join->thd->variables.join_buff_size, 2*len);
+ size_of_rec_ofs= offset_size(buff_size);
+ size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len);
+ size_of_fld_ofs= size_of_rec_len;
+ base_prefix_length= (with_length ? size_of_rec_len : 0) +
+ (prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
+ /*
+ The size of the offsets for referenced fields will be added later.
+ The values of 'pack_length' and 'pack_length_with_blob_ptrs' are adjusted
+ every time when the first reference to the referenced field is registered.
+ */
+ pack_length= (with_length ? size_of_rec_len : 0) +
+ (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) +
+ length;
+ pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *);
+}
+
+
+/*
+ Get maximum total length of all affixes of a record in the join cache buffer
+
+ SYNOPSIS
+ get_record_max_affix_length()
+
+ DESCRIPTION
+ The function calculates the maximum possible total length of all affixes
+ of a record in the join cache buffer, that is made of:
+ - the length of all prefixes used in this cache,
+ - the length of the match flag if it's needed
+ - the total length of the maximum possible offsets to the fields of
+ a record in the buffer.
+
+ RETURN VALUE
+ The maximum total length of all affixes of a record in the join buffer
+*/
+
+uint JOIN_CACHE::get_record_max_affix_length()
+{
+ uint len= get_prefix_length() +
+ test(with_match_flag) +
+ size_of_fld_ofs * data_field_count;
+ return len;
+}
+
+
+/*
+ Get the minimum possible size of the cache join buffer
+
+ SYNOPSIS
+ get_min_join_buffer_size()
+
+ DESCRIPTION
+ At the first its invocation for the cache the function calculates the
+ minimum possible size of the join buffer of the cache. This value depends
+ on the minimal number of records 'min_records' to be stored in the join
+ buffer. The number is supposed to be determined by the procedure that
+ chooses the best access path to the joined table join_tab in the execution
+ plan. After the calculation of the interesting size the function saves it
+ in the field 'min_buff_size' in order to use it directly at the next
+ invocations of the function.
+
+ NOTES
+ Currently the number of minimal records is just set to 1.
+
+ RETURN VALUE
+ The minimal possible size of the join buffer of this cache
+*/
+
+ulong JOIN_CACHE::get_min_join_buffer_size()
+{
+ if (!min_buff_size)
+ {
+ ulong len= 0;
+ for (JOIN_TAB *tab= join_tab-tables; tab < join_tab; tab++)
+ len+= tab->get_max_used_fieldlength();
+ len+= get_record_max_affix_length() + get_max_key_addon_space_per_record();
+ ulong min_sz= len*min_records;
+ ulong add_sz= 0;
+ for (uint i=0; i < min_records; i++)
+ add_sz+= join_tab_scan->aux_buffer_incr(i+1);
+ avg_aux_buffer_incr= add_sz/min_records;
+ min_sz+= add_sz;
+ min_sz+= pack_length_with_blob_ptrs;
+ min_buff_size= min_sz;
+ }
+ return min_buff_size;
+}
+
+
+/*
+ Get the maximum possible size of the cache join buffer
+
+ SYNOPSIS
+ get_max_join_buffer_size()
+
+ DESCRIPTION
+ At the first its invocation for the cache the function calculates the
+ maximum possible size of join buffer for the cache. This value does not
+ exceed the estimate of the number of records 'max_records' in the partial
+ join that joins tables from the first one through join_tab. This value
+ is also capped off by the value of join_tab->join_buffer_size_limit, if it
+ has been set a to non-zero value, and by the value of the system parameter
+ join_buffer_size - otherwise. After the calculation of the interesting size
+ the function saves the value in the field 'max_buff_size' in order to use
+ it directly at the next invocations of the function.
+
+ NOTES
+ Currently the value of join_tab->join_buffer_size_limit is initialized
+ to 0 and is never reset.
+
+ RETURN VALUE
+ The maximum possible size of the join buffer of this cache
+*/
+
+ulong JOIN_CACHE::get_max_join_buffer_size()
+{
+ if (!max_buff_size)
+ {
+ ulong max_sz;
+ ulong min_sz= get_min_join_buffer_size();
+ ulong len= 0;
+ for (JOIN_TAB *tab= join_tab-tables; tab < join_tab; tab++)
+ len+= tab->get_used_fieldlength();
+ len+= get_record_max_affix_length();
+ avg_record_length= len;
+ len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
+ space_per_record= len;
+
+ ulong limit_sz= join->thd->variables.join_buff_size;
+ if (join_tab->join_buffer_size_limit)
+ set_if_smaller(limit_sz, join_tab->join_buffer_size_limit);
+ if (limit_sz / max_records > space_per_record)
+ max_sz= space_per_record * max_records;
+ else
+ max_sz= limit_sz;
+ max_sz+= pack_length_with_blob_ptrs;
+ set_if_smaller(max_sz, limit_sz);
+ set_if_bigger(max_sz, min_sz);
+ max_buff_size= max_sz;
+ }
+ return max_buff_size;
+}
+
+
+/*
+ Allocate memory for a join buffer
+
+ SYNOPSIS
+ alloc_buffer()
+
+ DESCRIPTION
+ The function allocates a lump of memory for the cache join buffer.
+ Initially the function sets the size of the buffer buff_size equal to
+ the value returned by get_max_join_buffer_size(). If the total size of
+ the space intended to be used for the join buffers employed by the
+ tables from the first one through join_tab exceeds the value of the
+ system parameter join_buff_space_limit, then the function first tries
+ to shrink the used buffers to make the occupied space fit the maximum
+ memory allowed to be used for all join buffers in total. After
+ this the function tries to allocate a join buffer for join_tab.
+ If it fails to do so, it decrements the requested size of the join
+ buffer, shrinks proportionally the join buffers used for the previous
+ tables and tries to allocate a buffer for join_tab. In the case of a
+ failure the function repeats its attempts with smaller and smaller
+ requested sizes of the buffer, but not more than 4 times.
+
+ RETURN VALUE
+ 0 if the memory has been successfully allocated
+ 1 otherwise
+*/
+
+int JOIN_CACHE::alloc_buffer()
+{
+ JOIN_TAB *tab;
+ JOIN_CACHE *cache;
+ ulonglong curr_buff_space_sz= 0;
+ ulonglong curr_min_buff_space_sz= 0;
+ ulonglong join_buff_space_limit=
+ join->thd->variables.join_buff_space_limit;
+ double partial_join_cardinality= (join_tab-1)->get_partial_join_cardinality();
+ buff= NULL;
+ min_buff_size= 0;
+ max_buff_size= 0;
+ min_records= 1;
+ max_records= partial_join_cardinality <= join_buff_space_limit ?
+ (ulonglong) partial_join_cardinality : join_buff_space_limit;
+ set_if_bigger(max_records, 10);
+ min_buff_size= get_min_join_buffer_size();
+ buff_size= get_max_join_buffer_size();
+ for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++)
+ {
+ cache= tab->cache;
+ if (cache)
+ {
+ curr_min_buff_space_sz+= cache->get_min_join_buffer_size();
+ curr_buff_space_sz+= cache->get_join_buffer_size();
+ }
+ }
+
+ if (curr_min_buff_space_sz > join_buff_space_limit ||
+ (curr_buff_space_sz > join_buff_space_limit &&
+ join->shrink_join_buffers(join_tab, curr_buff_space_sz,
+ join_buff_space_limit)))
+ goto fail;
+
+ for (ulong buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; )
+ {
+ ulong next_buff_size;
+
+ if ((buff= (uchar*) my_malloc(buff_size, MYF(0))))
+ break;
+
+ next_buff_size= buff_size > buff_size_decr ? buff_size-buff_size_decr : 0;
+ if (next_buff_size < min_buff_size ||
+ join->shrink_join_buffers(join_tab, curr_buff_space_sz,
+ curr_buff_space_sz-buff_size_decr))
+ goto fail;
+ buff_size= next_buff_size;
+
+ curr_buff_space_sz= 0;
+ for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++)
+ {
+ cache= tab->cache;
+ if (cache)
+ curr_buff_space_sz+= cache->get_join_buffer_size();
+ }
+ }
+ return 0;
+
+fail:
+ buff_size= 0;
+ return 1;
+}
+
+
+/*
+ Shrink the size if the cache join buffer in a given ratio
+
+ SYNOPSIS
+ shrink_join_buffer_in_ratio()
+ n nominator of the ratio to shrink the buffer in
+ d denominator if the ratio
+
+ DESCRIPTION
+ The function first deallocates the join buffer of the cache. Then
+ it allocates a buffer that is (n/d) times smaller.
+
+ RETURN VALUE
+ FALSE on success with allocation of the smaller join buffer
+ TRUE otherwise
+*/
+
+bool JOIN_CACHE::shrink_join_buffer_in_ratio(ulonglong n, ulonglong d)
+{
+ ulonglong next_buff_size;
+ if (n < d)
+ return FALSE;
+ next_buff_size= (ulonglong) ((double) buff_size / n * d);
+ set_if_bigger(next_buff_size, min_buff_size);
+ buff_size= next_buff_size;
+ return realloc_buffer();
+}
+
+
+/*
+ Reallocate the join buffer of a join cache
+
+ SYNOPSIS
+ realloc_buffer()
+
+ DESCRITION
+ The function reallocates the join buffer of the join cache. After this
+ it resets the buffer for writing.
+
+ NOTES
+ The function assumes that buff_size contains the new value for the join
+ buffer size.
+
+ RETURN VALUE
+ 0 if the buffer has been successfully reallocated
+ 1 otherwise
+*/
+
+int JOIN_CACHE::realloc_buffer()
+{
+ int rc;
+ free();
+ rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(0))));
+ reset(TRUE);
+ return rc;
+}
+
+
+/*
+ Initialize a join cache
+
+ SYNOPSIS
+ init()
+
+ DESCRIPTION
+ The function initializes the join cache structure. It supposed to be called
+ by init methods for classes derived from the JOIN_CACHE.
+ The function allocates memory for the join buffer and for descriptors of
+ the record fields stored in the buffer.
+
+ NOTES
+ The code of this function should have been included into the constructor
+ code itself. However the new operator for the class JOIN_CACHE would
+ never fail while memory allocation for the join buffer is not absolutely
+ unlikely to fail. That's why this memory allocation has to be placed in a
+ separate function that is called in a couple with a cache constructor.
+ It is quite natural to put almost all other constructor actions into
+ this function.
+
+ RETURN VALUE
+ 0 initialization with buffer allocations has been succeeded
+ 1 otherwise
+*/
+
+int JOIN_CACHE::init()
+{
+ DBUG_ENTER("JOIN_CACHE::init");
+
+ calc_record_fields();
+
+ collect_info_on_key_args();
+
+ if (alloc_fields())
+ DBUG_RETURN(1);
+
+ create_flag_fields();
+
+ create_key_arg_fields();
+
+ create_remaining_fields();
+
+ set_constants();
+
+ if (alloc_buffer())
+ DBUG_RETURN(1);
+
+ reset(TRUE);
+
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Check the possibility to read the access keys directly from the join buffer
+ SYNOPSIS
+ check_emb_key_usage()
+
+ DESCRIPTION
+ The function checks some conditions at which the key values can be read
+ directly from the join buffer. This is possible when the key values can be
+ composed by concatenation of the record fields stored in the join buffer.
+ Sometimes when the access key is multi-component the function has to re-order
+ the fields written into the join buffer to make keys embedded. If key
+ values for the key access are detected as embedded then 'use_emb_key'
+ is set to TRUE.
+
+ EXAMPLE
+ Let table t2 has an index defined on the columns a,b . Let's assume also
+ that the columns t2.a, t2.b as well as the columns t1.a, t1.b are all
+ of the integer type. Then if the query
+ SELECT COUNT(*) FROM t1, t2 WHERE t1.a=t2.a and t1.b=t2.b
+ is executed with a join cache in such a way that t1 is the driving
+ table then the key values to access table t2 can be read directly
+ from the join buffer.
+
+ NOTES
+ In some cases key values could be read directly from the join buffer but
+ we still do not consider them embedded. In the future we'll expand the
+ the class of keys which we identify as embedded.
+
+ NOTES
+ The function returns FALSE if no key is used to join the records
+ from join_tab.
+
+ RETURN VALUE
+ TRUE key values will be considered as embedded,
+ FALSE otherwise.
+*/
+
+bool JOIN_CACHE::check_emb_key_usage()
+{
+
+ if (!is_key_access())
+ return FALSE;
+
+ uint i;
+ Item *item;
+ KEY_PART_INFO *key_part;
+ CACHE_FIELD *copy;
+ CACHE_FIELD *copy_end;
+ uint len= 0;
+ TABLE *table= join_tab->table;
+ TABLE_REF *ref= &join_tab->ref;
+ KEY *keyinfo= table->key_info+ref->key;
+
+ /*
+ If some of the key arguments are not from the local cache the key
+ is not considered as embedded.
+ TODO:
+ Expand it to the case when ref->key_parts=1 and local_key_arg_fields=0.
+ */
+ if (external_key_arg_fields != 0)
+ return FALSE;
+ /*
+ If the number of the local key arguments is not equal to the number
+ of key parts the key value cannot be read directly from the join buffer.
+ */
+ if (local_key_arg_fields != ref->key_parts)
+ return FALSE;
+
+ /*
+ A key is not considered embedded if one of the following is true:
+ - one of its key parts is not equal to a field
+ - it is a partial key
+ - definition of the argument field does not coincide with the
+ definition of the corresponding key component
+ - some of the key components are nullable
+ */
+ for (i=0; i < ref->key_parts; i++)
+ {
+ item= ref->items[i]->real_item();
+ if (item->type() != Item::FIELD_ITEM)
+ return FALSE;
+ key_part= keyinfo->key_part+i;
+ if (key_part->key_part_flag & HA_PART_KEY_SEG)
+ return FALSE;
+ if (!key_part->field->eq_def(((Item_field *) item)->field))
+ return FALSE;
+ if (key_part->field->maybe_null())
+ return FALSE;
+ }
+
+ copy= field_descr+flag_fields;
+ copy_end= copy+local_key_arg_fields;
+ for ( ; copy < copy_end; copy++)
+ {
+ /*
+ If some of the key arguments are of variable length the key
+ is not considered as embedded.
+ */
+ if (copy->type != 0)
+ return FALSE;
+ /*
+ If some of the key arguments are bit fields whose bits are partially
+ stored with null bits the key is not considered as embedded.
+ */
+ if (copy->field->type() == MYSQL_TYPE_BIT &&
+ ((Field_bit*) (copy->field))->bit_len)
+ return FALSE;
+ len+= copy->length;
+ }
+
+ emb_key_length= len;
+
+ /*
+ Make sure that key fields follow the order of the corresponding
+ key components these fields are equal to. For this the descriptors
+ of the fields that comprise the key might be re-ordered.
+ */
+ for (i= 0; i < ref->key_parts; i++)
+ {
+ uint j;
+ Item *item= ref->items[i]->real_item();
+ Field *fld= ((Item_field *) item)->field;
+ CACHE_FIELD *init_copy= field_descr+flag_fields+i;
+ for (j= i, copy= init_copy; i < local_key_arg_fields; i++, copy++)
+ {
+ if (fld->eq(copy->field))
+ {
+ if (j != i)
+ {
+ CACHE_FIELD key_part_copy= *copy;
+ *copy= *init_copy;
+ *init_copy= key_part_copy;
+ }
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ Write record fields and their required offsets into the join cache buffer
+
+ SYNOPSIS
+ write_record_data()
+ link a reference to the associated info in the previous cache
+ is_full OUT true if it has been decided that no more records will be
+ added to the join buffer
+
+ DESCRIPTION
+ This function put into the cache buffer the following info that it reads
+ from the join record buffers or computes somehow:
+ (1) the length of all fields written for the record (optional)
+ (2) an offset to the associated info in the previous cache (if there is any)
+ determined by the link parameter
+ (3) all flag fields of the tables whose data field are put into the cache:
+ - match flag (optional),
+ - null bitmaps for all tables,
+ - null row flags for all tables
+ (4) values of all data fields including
+ - full images of those fixed legth data fields that cannot have
+ trailing spaces
+ - significant part of fixed length fields that can have trailing spaces
+ with the prepanded length
+ - data of non-blob variable length fields with the prepanded data length
+ - blob data from blob fields with the prepanded data length
+ (5) record offset values for the data fields that are referred to from
+ other caches
+
+ The record is written at the current position stored in the field 'pos'.
+ At the end of the function 'pos' points at the position right after the
+ written record data.
+ The function increments the number of records in the cache that is stored
+ in the 'records' field by 1. The function also modifies the values of
+ 'curr_rec_pos' and 'last_rec_pos' to point to the written record.
+ The 'end_pos' cursor is modified accordingly.
+ The 'last_rec_blob_data_is_in_rec_buff' is set on if the blob data
+ remains in the record buffers and not copied to the join buffer. It may
+ happen only to the blob data from the last record added into the cache.
+ If on_precond is attached to join_tab and it is not evaluated to TRUE
+ then MATCH_IMPOSSIBLE is placed in the match flag field of the record
+ written into the join buffer.
+
+ RETURN VALUE
+ length of the written record data
+*/
+
+uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
+{
+ uint len;
+ bool last_record;
+ CACHE_FIELD *copy;
+ CACHE_FIELD *copy_end;
+ uchar *flags_pos;
+ uchar *cp= pos;
+ uchar *init_pos= cp;
+ uchar *rec_len_ptr= 0;
+ uint key_extra= extra_key_length();
+
+ records++; /* Increment the counter of records in the cache */
+
+ len= pack_length + key_extra;
+
+ /* Make an adjustment for the size of the auxiliary buffer if there is any */
+ uint incr= aux_buffer_incr(records);
+ ulong rem= rem_space();
+ aux_buff_size+= len+incr < rem ? incr : rem;
+
+ /*
+ For each blob to be put into cache save its length and a pointer
+ to the value in the corresponding element of the blob_ptr array.
+ Blobs with null values are skipped.
+ Increment 'len' by the total length of all these blobs.
+ */
+ if (blobs)
+ {
+ CACHE_FIELD **copy_ptr= blob_ptr;
+ CACHE_FIELD **copy_ptr_end= copy_ptr+blobs;
+ for ( ; copy_ptr < copy_ptr_end; copy_ptr++)
+ {
+ Field_blob *blob_field= (Field_blob *) (*copy_ptr)->field;
+ if (!blob_field->is_null())
+ {
+ uint blob_len= blob_field->get_length();
+ (*copy_ptr)->blob_length= blob_len;
+ len+= blob_len;
+ blob_field->get_ptr(&(*copy_ptr)->str);
+ }
+ }
+ }
+
+ /*
+ Check whether we won't be able to add any new record into the cache after
+ this one because the cache will be full. Set last_record to TRUE if it's so.
+ The assume that the cache will be full after the record has been written
+ into it if either the remaining space of the cache is not big enough for the
+ record's blob values or if there is a chance that not all non-blob fields
+ of the next record can be placed there.
+ This function is called only in the case when there is enough space left in
+ the cache to store at least non-blob parts of the current record.
+ */
+ last_record= (len+pack_length_with_blob_ptrs+key_extra) > rem_space();
+
+ /*
+ Save the position for the length of the record in the cache if it's needed.
+ The length of the record will be inserted here when all fields of the record
+ are put into the cache.
+ */
+ if (with_length)
+ {
+ rec_len_ptr= cp;
+ cp+= size_of_rec_len;
+ }
+
+ /*
+ Put a reference to the fields of the record that are stored in the previous
+ cache if there is any. This reference is passed by the 'link' parameter.
+ */
+ if (prev_cache)
+ {
+ cp+= prev_cache->get_size_of_rec_offset();
+ prev_cache->store_rec_ref(cp, link);
+ }
+
+ curr_rec_pos= cp;
+
+ /* If the there is a match flag set its value to 0 */
+ copy= field_descr;
+ if (with_match_flag)
+ *copy[0].str= 0;
+
+ /* First put into the cache the values of all flag fields */
+ copy_end= field_descr+flag_fields;
+ flags_pos= cp;
+ for ( ; copy < copy_end; copy++)
+ {
+ memcpy(cp, copy->str, copy->length);
+ cp+= copy->length;
+ }
+
+ /* Now put the values of the remaining fields as soon as they are not nulls */
+ copy_end= field_descr+fields;
+ for ( ; copy < copy_end; copy++)
+ {
+ Field *field= copy->field;
+ if (field && field->maybe_null() && field->is_null())
+ {
+ /* Do not copy a field if its value is null */
+ if (copy->referenced_field_no)
+ copy->offset= 0;
+ continue;
+ }
+ /* Save the offset of the field to put it later at the end of the record */
+ if (copy->referenced_field_no)
+ copy->offset= cp-curr_rec_pos;
+
+ if (copy->type == CACHE_BLOB)
+ {
+ Field_blob *blob_field= (Field_blob *) copy->field;
+ if (last_record)
+ {
+ last_rec_blob_data_is_in_rec_buff= 1;
+ /* Put down the length of the blob and the pointer to the data */
+ blob_field->get_image(cp, copy->length+sizeof(char*),
+ blob_field->charset());
+ cp+= copy->length+sizeof(char*);
+ }
+ else
+ {
+ /* First put down the length of the blob and then copy the data */
+ blob_field->get_image(cp, copy->length,
+ blob_field->charset());
+ memcpy(cp+copy->length, copy->str, copy->blob_length);
+ cp+= copy->length+copy->blob_length;
+ }
+ }
+ else
+ {
+ switch (copy->type) {
+ case CACHE_VARSTR1:
+ /* Copy the significant part of the short varstring field */
+ len= (uint) copy->str[0] + 1;
+ 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;
+ memcpy(cp, copy->str, len);
+ cp+= len;
+ break;
+ case CACHE_STRIPPED:
+ {
+ /*
+ Put down the field value stripping all trailing spaces off.
+ After this insert the length of the written sequence of bytes.
+ */
+ uchar *str, *end;
+ for (str= copy->str, end= str+copy->length;
+ end > str && end[-1] == ' ';
+ end--) ;
+ len=(uint) (end-str);
+ int2store(cp, len);
+ memcpy(cp+2, str, len);
+ cp+= len+2;
+ break;
+ }
+ default:
+ /* Copy the entire image of the field from the record buffer */
+ memcpy(cp, copy->str, copy->length);
+ cp+= copy->length;
+ }
+ }
+ }
+
+ /* Add the offsets of the fields that are referenced from other caches */
+ if (referenced_fields)
+ {
+ uint cnt= 0;
+ for (copy= field_descr+flag_fields; copy < copy_end ; copy++)
+ {
+ if (copy->referenced_field_no)
+ {
+ store_fld_offset(cp+size_of_fld_ofs*(copy->referenced_field_no-1),
+ copy->offset);
+ cnt++;
+ }
+ }
+ cp+= size_of_fld_ofs*cnt;
+ }
+
+ if (rec_len_ptr)
+ store_rec_length(rec_len_ptr, (ulong) (cp-rec_len_ptr-size_of_rec_len));
+ last_rec_pos= curr_rec_pos;
+ end_pos= pos= cp;
+ *is_full= last_record;
+
+ last_written_is_null_compl= 0;
+ if (!join_tab->first_unmatched && join_tab->on_precond)
+ {
+ join_tab->found= 0;
+ join_tab->not_null_compl= 1;
+ if (!join_tab->on_precond->val_int())
+ {
+ flags_pos[0]= MATCH_IMPOSSIBLE;
+ last_written_is_null_compl= 1;
+ }
+ }
+
+ return (uint) (cp-init_pos);
+}
+
+
+/*
+ Reset the join buffer for reading/writing: default implementation
+
+ SYNOPSIS
+ reset()
+ for_writing if it's TRUE the function reset the buffer for writing
+
+ DESCRIPTION
+ This default implementation of the virtual function reset() resets
+ the join buffer for reading or writing.
+ If the buffer is reset for reading only the 'pos' value is reset
+ to point to the very beginning of the join buffer. If the buffer is
+ reset for writing additionally:
+ - the counter of the records in the buffer is set to 0,
+ - the the value of 'last_rec_pos' gets pointing at the position just
+ before the buffer,
+ - 'end_pos' is set to point to the beginning of the join buffer,
+ - the size of the auxiliary buffer is reset to 0,
+ - the flag 'last_rec_blob_data_is_in_rec_buff' is set to 0.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::reset(bool for_writing)
+{
+ pos= buff;
+ curr_rec_link= 0;
+ if (for_writing)
+ {
+ records= 0;
+ last_rec_pos= buff;
+ aux_buff_size= 0;
+ end_pos= pos;
+ last_rec_blob_data_is_in_rec_buff= 0;
+ }
+}
+
+
+/*
+ Add a record into the join buffer: the default implementation
+
+ SYNOPSIS
+ put_record()
+
+ DESCRIPTION
+ This default implementation of the virtual function put_record writes
+ the next matching record into the join buffer.
+ It also links the record having been written into the join buffer with
+ the matched record in the previous cache if there is any.
+ The implementation assumes that the function get_curr_link()
+ will return exactly the pointer to this matched record.
+
+ RETURN VALUE
+ TRUE if it has been decided that it should be the last record
+ in the join buffer,
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE::put_record()
+{
+ bool is_full;
+ uchar *link= 0;
+ if (prev_cache)
+ link= prev_cache->get_curr_rec_link();
+ write_record_data(link, &is_full);
+ return is_full;
+}
+
+
+/*
+ Read the next record from the join buffer: the default implementation
+
+ SYNOPSIS
+ get_record()
+
+ DESCRIPTION
+ This default implementation of the virtual function get_record
+ reads fields of the next record from the join buffer of this cache.
+ The function also reads all other fields associated with this record
+ from the the join buffers of the previous caches. The fields are read
+ into the corresponding record buffers.
+ It is supposed that 'pos' points to the position in the buffer
+ right after the previous record when the function is called.
+ When the function returns the 'pos' values is updated to point
+ to the position after the read record.
+ The value of 'curr_rec_pos' is also updated by the function to
+ point to the beginning of the first field of the record in the
+ join buffer.
+
+ RETURN VALUE
+ TRUE there are no more records to read from the join buffer
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE::get_record()
+{
+ bool res;
+ uchar *prev_rec_ptr= 0;
+ if (with_length)
+ pos+= size_of_rec_len;
+ if (prev_cache)
+ {
+ pos+= prev_cache->get_size_of_rec_offset();
+ prev_rec_ptr= prev_cache->get_rec_ref(pos);
+ }
+ curr_rec_pos= pos;
+ if (!(res= read_all_record_fields() == NO_MORE_RECORDS_IN_BUFFER))
+ {
+ pos+= referenced_fields*size_of_fld_ofs;
+ if (prev_cache)
+ prev_cache->get_record_by_pos(prev_rec_ptr);
+ }
+ return res;
+}
+
+
+/*
+ Read a positioned record from the join buffer: the default implementation
+
+ SYNOPSIS
+ get_record_by_pos()
+ rec_ptr position of the first field of the record in the join buffer
+
+ DESCRIPTION
+ This default implementation of the virtual function get_record_pos
+ reads the fields of the record positioned at 'rec_ptr' from the join buffer.
+ The function also reads all other fields associated with this record
+ from the the join buffers of the previous caches. The fields are read
+ into the corresponding record buffers.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::get_record_by_pos(uchar *rec_ptr)
+{
+ uchar *save_pos= pos;
+ pos= rec_ptr;
+ read_all_record_fields();
+ pos= save_pos;
+ if (prev_cache)
+ {
+ uchar *prev_rec_ptr= prev_cache->get_rec_ref(rec_ptr);
+ prev_cache->get_record_by_pos(prev_rec_ptr);
+ }
+}
+
+
+/*
+ Get the match flag from the referenced record: the default implementation
+
+ SYNOPSIS
+ get_match_flag_by_pos()
+ rec_ptr position of the first field of the record in the join buffer
+
+ DESCRIPTION
+ This default implementation of the virtual function get_match_flag_by_pos
+ get the match flag for the record pointed by the reference at the position
+ rec_ptr. If the match flag is placed in one of the previous buffers the
+ function first reaches the linked record fields in this buffer.
+
+ RETURN VALUE
+ match flag for the record at the position rec_ptr
+*/
+
+enum JOIN_CACHE::Match_flag JOIN_CACHE::get_match_flag_by_pos(uchar *rec_ptr)
+{
+ Match_flag match_fl= MATCH_NOT_FOUND;
+ if (with_match_flag)
+ {
+ match_fl= (enum Match_flag) rec_ptr[0];
+ return match_fl;
+ }
+ if (prev_cache)
+ {
+ uchar *prev_rec_ptr= prev_cache->get_rec_ref(rec_ptr);
+ return prev_cache->get_match_flag_by_pos(prev_rec_ptr);
+ }
+ DBUG_ASSERT(0);
+ return match_fl;
+}
+
+
+/*
+ Calculate the increment of the auxiliary buffer for a record write
+
+ SYNOPSIS
+ aux_buffer_incr()
+ recno the number of the record the increment to be calculated for
+
+ DESCRIPTION
+ This function calls the aux_buffer_incr the method of the
+ companion member join_tab_scan to calculate the growth of the
+ auxiliary buffer when the recno-th record is added to the
+ join_buffer of this cache.
+
+ RETURN VALUE
+ the number of bytes in the increment
+*/
+
+uint JOIN_CACHE::aux_buffer_incr(ulong recno)
+{
+ return join_tab_scan->aux_buffer_incr(recno);
+}
+
+/*
+ Read all flag and data fields of a record from the join buffer
+
+ SYNOPSIS
+ read_all_record_fields()
+
+ DESCRIPTION
+ The function reads all flag and data fields of a record from the join
+ buffer into the corresponding record buffers.
+ The fields are read starting from the position 'pos' which is
+ supposed to point to the beginning og the first record field.
+ The function increments the value of 'pos' by the length of the
+ read data.
+
+ RETURN VALUE
+ (-1) if there is no more records in the join buffer
+ length of the data read from the join buffer - otherwise
+*/
+
+uint JOIN_CACHE::read_all_record_fields()
+{
+ uchar *init_pos= pos;
+
+ if (pos > last_rec_pos || !records)
+ return NO_MORE_RECORDS_IN_BUFFER;
+
+ /* First match flag, read null bitmaps and null_row flag for each table */
+ read_flag_fields();
+
+ /* Now read the remaining table fields if needed */
+ CACHE_FIELD *copy= field_descr+flag_fields;
+ CACHE_FIELD *copy_end= field_descr+fields;
+ bool blob_in_rec_buff= blob_data_is_in_rec_buff(init_pos);
+ for ( ; copy < copy_end; copy++)
+ read_record_field(copy, blob_in_rec_buff);
+
+ return (uint) (pos-init_pos);
+}
+
+
+/*
+ Read all flag fields of a record from the join buffer
+
+ SYNOPSIS
+ read_flag_fields()
+
+ DESCRIPTION
+ The function reads all flag fields of a record from the join
+ buffer into the corresponding record buffers.
+ The fields are read starting from the position 'pos'.
+ The function increments the value of 'pos' by the length of the
+ read data.
+
+ RETURN VALUE
+ length of the data read from the join buffer
+*/
+
+uint JOIN_CACHE::read_flag_fields()
+{
+ uchar *init_pos= pos;
+ CACHE_FIELD *copy= field_descr;
+ CACHE_FIELD *copy_end= copy+flag_fields;
+ if (with_match_flag)
+ {
+ copy->str[0]= test((Match_flag) pos[0] == MATCH_FOUND);
+ pos+= copy->length;
+ copy++;
+ }
+ for ( ; copy < copy_end; copy++)
+ {
+ memcpy(copy->str, pos, copy->length);
+ pos+= copy->length;
+ }
+ return (pos-init_pos);
+}
+
+
+/*
+ Read a data record field from the join buffer
+
+ SYNOPSIS
+ read_record_field()
+ copy the descriptor of the data field to be read
+ blob_in_rec_buff indicates whether this is the field from the record
+ whose blob data are in record buffers
+
+ DESCRIPTION
+ The function reads the data field specified by the parameter copy
+ from the join buffer into the corresponding record buffer.
+ The field is read starting from the position 'pos'.
+ The data of blob values is not copied from the join buffer.
+ The function increments the value of 'pos' by the length of the
+ read data.
+
+ RETURN VALUE
+ length of the data read from the join buffer
+*/
+
+uint JOIN_CACHE::read_record_field(CACHE_FIELD *copy, bool blob_in_rec_buff)
+{
+ uint len;
+ /* Do not copy the field if its value is null */
+ if (copy->field && copy->field->maybe_null() && copy->field->is_null())
+ return 0;
+ if (copy->type == CACHE_BLOB)
+ {
+ Field_blob *blob_field= (Field_blob *) copy->field;
+ /*
+ Copy the length and the pointer to data but not the blob data
+ itself to the record buffer
+ */
+ if (blob_in_rec_buff)
+ {
+ blob_field->set_image(pos, copy->length+sizeof(char*),
+ blob_field->charset());
+ len= copy->length+sizeof(char*);
+ }
+ else
+ {
+ blob_field->set_ptr(pos, pos+copy->length);
+ len= copy->length+blob_field->get_length();
+ }
+ }
+ else
+ {
+ switch (copy->type) {
+ case CACHE_VARSTR1:
+ /* Copy the significant part of the short varstring field */
+ len= (uint) pos[0] + 1;
+ memcpy(copy->str, pos, len);
+ break;
+ case CACHE_VARSTR2:
+ /* Copy the significant part of the long varstring field */
+ len= uint2korr(pos) + 2;
+ memcpy(copy->str, pos, len);
+ break;
+ case CACHE_STRIPPED:
+ /* Pad the value by spaces that has been stripped off */
+ len= uint2korr(pos);
+ memcpy(copy->str, pos+2, len);
+ memset(copy->str+len, ' ', copy->length-len);
+ len+= 2;
+ break;
+ default:
+ /* Copy the entire image of the field from the record buffer */
+ len= copy->length;
+ memcpy(copy->str, pos, len);
+ }
+ }
+ pos+= len;
+ return len;
+}
+
+
+/*
+ Read a referenced field from the join buffer
+
+ SYNOPSIS
+ read_referenced_field()
+ copy pointer to the descriptor of the referenced field
+ rec_ptr pointer to the record that may contain this field
+ len IN/OUT total length of the record fields
+
+ DESCRIPTION
+ The function checks whether copy points to a data field descriptor
+ for this cache object. If it does not then the function returns
+ FALSE. Otherwise the function reads the field of the record in
+ the join buffer pointed by 'rec_ptr' into the corresponding record
+ buffer and returns TRUE.
+ If the value of *len is 0 then the function sets it to the total
+ length of the record fields including possible trailing offset
+ values. Otherwise *len is supposed to provide this value that
+ has been obtained earlier.
+
+ NOTE
+ If the value of the referenced field is null then the offset
+ for the value is set to 0. If the value of a field can be null
+ then the value of flag_fields is always positive. So the offset
+ for any non-null value cannot be 0 in this case.
+
+ RETURN VALUE
+ TRUE 'copy' points to a data descriptor of this join cache
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE::read_referenced_field(CACHE_FIELD *copy,
+ uchar *rec_ptr,
+ uint *len)
+{
+ uchar *ptr;
+ uint offset;
+ if (copy < field_descr || copy >= field_descr+fields)
+ return FALSE;
+ if (!*len)
+ {
+ /* Get the total length of the record fields */
+ uchar *len_ptr= rec_ptr;
+ if (prev_cache)
+ len_ptr-= prev_cache->get_size_of_rec_offset();
+ *len= get_rec_length(len_ptr-size_of_rec_len);
+ }
+
+ ptr= rec_ptr-(prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
+ offset= get_fld_offset(ptr+ *len -
+ size_of_fld_ofs*
+ (referenced_fields+1-copy->referenced_field_no));
+ bool is_null= FALSE;
+ Field *field= copy->field;
+ if (offset == 0 && flag_fields)
+ is_null= TRUE;
+ if (is_null)
+ {
+ field->set_null();
+ if (!field->real_maybe_null())
+ field->table->null_row= 1;
+ }
+ else
+ {
+ uchar *save_pos= pos;
+ field->set_notnull();
+ if (!field->real_maybe_null())
+ field->table->null_row= 0;
+ pos= rec_ptr+offset;
+ read_record_field(copy, blob_data_is_in_rec_buff(rec_ptr));
+ pos= save_pos;
+ }
+ return TRUE;
+}
+
+
+/*
+ Skip record from join buffer if's already matched: default implementation
+
+ SYNOPSIS
+ skip_if_matched()
+
+ DESCRIPTION
+ This default implementation of the virtual function skip_if_matched
+ skips the next record from the join buffer if its match flag is set to
+ MATCH_FOUND.
+ If the record is skipped the value of 'pos' is set to point to the position
+ right after the record.
+
+ RETURN VALUE
+ TRUE the match flag is set to MATCH_FOUND and the record has been skipped
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE::skip_if_matched()
+{
+ DBUG_ASSERT(with_length);
+ uint offset= size_of_rec_len;
+ if (prev_cache)
+ offset+= prev_cache->get_size_of_rec_offset();
+ /* Check whether the match flag is MATCH_FOUND */
+ if (get_match_flag_by_pos(pos+offset) == MATCH_FOUND)
+ {
+ pos+= size_of_rec_len + get_rec_length(pos);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Skip record from join buffer if the match isn't needed: default implementation
+
+ SYNOPSIS
+ skip_if_not_needed_match()
+
+ DESCRIPTION
+ This default implementation of the virtual function skip_if_not_needed_match
+ skips the next record from the join buffer if its match flag is not
+ MATCH_NOT_FOUND, and, either its value is MATCH_FOUND and join_tab is the
+ first inner table of an inner join, or, its value is MATCH_IMPOSSIBLE
+ and join_tab is the first inner table of an outer join.
+ If the record is skipped the value of 'pos' is set to point to the position
+ right after the record.
+
+ RETURN VALUE
+ TRUE the record has to be skipped
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE::skip_if_not_needed_match()
+{
+ DBUG_ASSERT(with_length);
+ enum Match_flag match_fl;
+ uint offset= size_of_rec_len;
+ if (prev_cache)
+ offset+= prev_cache->get_size_of_rec_offset();
+
+ if ((match_fl= get_match_flag_by_pos(pos+offset)) != MATCH_NOT_FOUND &&
+ (join_tab->check_only_first_match() == (match_fl == MATCH_FOUND)) )
+ {
+ pos+= size_of_rec_len + get_rec_length(pos);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Restore the fields of the last record from the join buffer
+
+ SYNOPSIS
+ restore_last_record()
+
+ DESCRIPTION
+ This function restore the values of the fields of the last record put
+ into join buffer in record buffers. The values most probably have been
+ overwritten by the field values from other records when they were read
+ from the join buffer into the record buffer in order to check pushdown
+ predicates.
+
+ RETURN
+ none
+*/
+
+void JOIN_CACHE::restore_last_record()
+{
+ if (records)
+ get_record_by_pos(last_rec_pos);
+}
+
+
+/*
+ Join records from the join buffer with records from the next join table
+
+ SYNOPSIS
+ join_records()
+ skip_last do not find matches for the last record from the buffer
+
+ DESCRIPTION
+ The functions extends all records from the join buffer by the matched
+ records from join_tab. In the case of outer join operation it also
+ adds null complementing extensions for the records from the join buffer
+ that have no match.
+ No extensions are generated for the last record from the buffer if
+ skip_last is true.
+
+ NOTES
+ The function must make sure that if linked join buffers are used then
+ a join buffer cannot be refilled again until all extensions in the
+ buffers chained to this one are generated.
+ Currently an outer join operation with several inner tables always uses
+ at least two linked buffers with the match join flags placed in the
+ first buffer. Any record composed of rows of the inner tables that
+ matches a record in this buffer must refer to the position of the
+ corresponding match flag.
+
+ IMPLEMENTATION
+ When generating extensions for outer tables of an outer join operation
+ first we generate all extensions for those records from the join buffer
+ that have matches, after which null complementing extension for all
+ unmatched records from the join buffer are generated.
+
+ RETURN VALUE
+ return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
+*/
+
+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();
+
+ if (outer_join_first_inner && !join_tab->first_unmatched)
+ join_tab->not_null_compl= TRUE;
+
+ if (!join_tab->first_unmatched)
+ {
+ /* Find all records from join_tab that match records from join buffer */
+ rc= join_matching_records(skip_last);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ goto finish;
+ if (outer_join_first_inner)
+ {
+ if (next_cache)
+ {
+ /*
+ Ensure that all matches for outer records from join buffer are to be
+ found. Now we ensure that all full records are found for records from
+ join buffer. Generally this is an overkill.
+ TODO: Ensure that only matches of the inner table records have to be
+ found for the records from join buffer.
+ */
+ rc= next_cache->join_records(skip_last);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ goto finish;
+ }
+ join_tab->not_null_compl= FALSE;
+ /* Prepare for generation of null complementing extensions */
+ for (tab= join_tab->first_inner; tab <= join_tab->last_inner; tab++)
+ tab->first_unmatched= join_tab->first_inner;
+ }
+ }
+ if (join_tab->first_unmatched)
+ {
+ if (is_key_access())
+ restore_last_record();
+
+ /*
+ Generate all null complementing extensions for the records from
+ join buffer that don't have any matching rows from the inner tables.
+ */
+ reset(FALSE);
+ rc= join_null_complements(skip_last);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ goto finish;
+ }
+ if(next_cache)
+ {
+ /*
+ When using linked caches we must ensure the records in the next caches
+ that refer to the records in the join buffer are fully extended.
+ Otherwise we could have references to the records that have been
+ already erased from the join buffer and replaced for new records.
+ */
+ rc= next_cache->join_records(skip_last);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ goto finish;
+ }
+ if (outer_join_first_inner)
+ {
+ /*
+ All null complemented rows have been already generated for all
+ outer records from join buffer. Restore the state of the
+ first_unmatched values to 0 to avoid another null complementing.
+ */
+ for (tab= join_tab->first_inner; tab <= join_tab->last_inner; tab++)
+ tab->first_unmatched= 0;
+ }
+
+ if (skip_last)
+ {
+ DBUG_ASSERT(!is_key_access());
+ /*
+ Restore the last record from the join buffer to generate
+ all extentions for it.
+ */
+ get_record();
+ }
+
+finish:
+ restore_last_record();
+ reset(TRUE);
+ return rc;
+}
+
+
+/*
+ Find matches from the next table for records from the join buffer
+
+ SYNOPSIS
+ join_matching_records()
+ skip_last do not look for matches for the last partial join record
+
+ DESCRIPTION
+ The function retrieves rows of the join_tab table and checks whether they
+ match partial join records from the join buffer. If a match is found
+ the function will call the sub_select function trying to look for matches
+ for the remaining join operations.
+ This function currently is called only from the function join_records.
+ If the value of skip_last is true the function writes the partial join
+ record from the record buffer into the join buffer to save its value for
+ the future processing in the caller function.
+
+ NOTES
+ If employed by BNL or BNLH join algorithms the function performs a full
+ scan of join_tab for each refill of the join buffer. If BKA or BKAH
+ algorithms are used then the function iterates only over those records
+ from join_tab that can be accessed by keys built over records in the join
+ buffer. To apply a proper method of iteration the function just calls
+ virtual iterator methods (open, next, close) of the member join_tab_scan.
+ The member can be either of the JOIN_TAB_SCAN or JOIN_TAB_SCAN_MMR type.
+ The class JOIN_TAB_SCAN provides the iterator methods for BNL/BNLH join
+ algorithms. The class JOIN_TAB_SCAN_MRR provides the iterator methods
+ for BKA/BKAH join algorithms.
+ When the function looks for records from the join buffer that would
+ match a record from join_tab it iterates either over all records in
+ the buffer or only over selected records. If BNL join operation is
+ performed all records are checked for the match. If BNLH or BKAH
+ algorithm is employed to join join_tab then the function looks only
+ through the records with the same join key as the record from join_tab.
+ With the BKA join algorithm only one record from the join buffer is checked
+ for a match for any record from join_tab. To iterate over the candidates
+ for a match the virtual function get_next_candidate_for_match is used,
+ while the virtual function prepare_look_for_matches is called to prepare
+ for such iteration proccess.
+
+ NOTES
+ The function produces all matching extensions for the records in the
+ join buffer following the path of the employed blocked algorithm.
+ When an outer join operation is performed all unmatched records from
+ the join buffer must be extended by null values. The function
+ 'join_null_complements' serves this purpose.
+
+ RETURN VALUE
+ return one of enum_nested_loop_state
+*/
+
+enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
+{
+ int error;
+ enum_nested_loop_state rc= NESTED_LOOP_OK;
+ 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();
+
+ /* Return at once if there are no records in the join buffer */
+ if (!records)
+ return NESTED_LOOP_OK;
+
+ /*
+ When joining we read records from the join buffer back into record buffers.
+ If matches for the last partial join record are found through a call to
+ the sub_select function then this partial join record must be saved in the
+ join buffer in order to be restored just before the sub_select call.
+ */
+ if (skip_last)
+ put_record();
+
+ if (join_tab->use_quick == 2 && join_tab->select->quick)
+ {
+ /* A dynamic range access was used last. Clean up after it */
+ delete join_tab->select->quick;
+ join_tab->select->quick= 0;
+ }
+
+ /* Prepare to retrieve all records of the joined table */
+ if ((error= join_tab_scan->open()))
+ goto finish; /* psergey-note: if this returns error, we will assert in net_send_statement() */
+
+ while (!(error= join_tab_scan->next()))
+ {
+ if (join->thd->killed)
+ {
+ /* The user has aborted the execution of the query */
+ join->thd->send_kill_message();
+ rc= NESTED_LOOP_KILLED;
+ goto finish;
+ }
+
+ if (join_tab->keep_current_rowid)
+ join_tab->table->file->position(join_tab->table->record[0]);
+
+ /* Prepare to read matching candidates from the join buffer */
+ if (prepare_look_for_matches(skip_last))
+ continue;
+
+ uchar *rec_ptr;
+ /* Read each possible candidate from the buffer and look for matches */
+ while ((rec_ptr= get_next_candidate_for_match()))
+ {
+ /*
+ If only the first match is needed, and, it has been already found for
+ the next record read from the join buffer, then the record is skipped.
+ Also those records that must be null complemented are not considered
+ as candidates for matches.
+ */
+ if ((!check_only_first_match && !outer_join_first_inner) ||
+ !skip_next_candidate_for_match(rec_ptr))
+ {
+ read_next_candidate_for_match(rec_ptr);
+ rc= generate_full_extensions(rec_ptr);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ goto finish;
+ }
+ }
+ }
+
+finish:
+ if (error)
+ rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
+ join_tab_scan->close();
+ return rc;
+}
+
+
+/*
+ Set match flag for a record in join buffer if it has not been set yet
+
+ SYNOPSIS
+ set_match_flag_if_none()
+ first_inner the join table to which this flag is attached to
+ rec_ptr pointer to the record in the join buffer
+
+ DESCRIPTION
+ If the records of the table are accumulated in a join buffer the function
+ sets the match flag for the record in the buffer that is referred to by
+ the record from this cache positioned at 'rec_ptr'.
+ The function also sets the match flag 'found' of the table first inner
+ if it has not been set before.
+
+ NOTES
+ The function assumes that the match flag for any record in any cache
+ is placed in the first byte occupied by the record fields.
+
+ RETURN VALUE
+ TRUE the match flag is set by this call for the first time
+ FALSE the match flag has been set before this call
+*/
+
+bool JOIN_CACHE::set_match_flag_if_none(JOIN_TAB *first_inner,
+ uchar *rec_ptr)
+{
+ if (!first_inner->cache)
+ {
+ /*
+ Records of the first inner table to which the flag is attached to
+ are not accumulated in a join buffer.
+ */
+ if (first_inner->found)
+ return FALSE;
+ else
+ {
+ first_inner->found= 1;
+ return TRUE;
+ }
+ }
+ JOIN_CACHE *cache= this;
+ while (cache->join_tab != first_inner)
+ {
+ cache= cache->prev_cache;
+ DBUG_ASSERT(cache);
+ rec_ptr= cache->get_rec_ref(rec_ptr);
+ }
+ if ((Match_flag) rec_ptr[0] != MATCH_FOUND)
+ {
+ rec_ptr[0]= MATCH_FOUND;
+ first_inner->found= 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Generate all full extensions for a partial join record in the buffer
+
+ SYNOPSIS
+ generate_full_extensions()
+ rec_ptr pointer to the record from join buffer to generate extensions
+
+ DESCRIPTION
+ The function first checks whether the current record of 'join_tab' matches
+ the partial join record from join buffer located at 'rec_ptr'. If it is the
+ case the function calls the join_tab->next_select method to generate
+ all full extension for this partial join match.
+
+ RETURN VALUE
+ return one of enum_nested_loop_state.
+*/
+
+enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
+{
+ enum_nested_loop_state rc= NESTED_LOOP_OK;
+
+ /*
+ Check whether the extended partial join record meets
+ the pushdown conditions.
+ */
+ if (check_match(rec_ptr))
+ {
+ int res= 0;
+
+ if (!join_tab->check_weed_out_table ||
+ !(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
+ {
+ set_curr_rec_link(rec_ptr);
+ rc= (join_tab->next_select)(join, join_tab+1, 0);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ {
+ reset(TRUE);
+ return rc;
+ }
+ }
+ if (res == -1)
+ {
+ rc= NESTED_LOOP_ERROR;
+ return rc;
+ }
+ }
+ return rc;
+}
+
+
+/*
+ Check matching to a partial join record from the join buffer
+
+ SYNOPSIS
+ check_match()
+ rec_ptr pointer to the record from join buffer to check matching to
+
+ DESCRIPTION
+ The function checks whether the current record of 'join_tab' matches
+ the partial join record from join buffer located at 'rec_ptr'. If this is
+ the case and 'join_tab' is the last inner table of a semi-join or an outer
+ join the function turns on the match flag for the 'rec_ptr' record unless
+ it has been already set.
+
+ NOTES
+ Setting the match flag on can trigger re-evaluation of pushdown conditions
+ for the record when join_tab is the last inner table of an outer join.
+
+ RETURN VALUE
+ TRUE there is a match
+ FALSE there is no match
+*/
+
+inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
+{
+ /* Check whether pushdown conditions are satisfied */
+ if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0)
+ return FALSE;
+
+ if (!join_tab->is_last_inner_table())
+ return TRUE;
+
+ /*
+ This is the last inner table of an outer join,
+ and maybe of other embedding outer joins, or
+ this is the last inner table of a semi-join.
+ */
+ JOIN_TAB *first_inner= join_tab->get_first_inner_table();
+ do
+ {
+ set_match_flag_if_none(first_inner, rec_ptr);
+ if (first_inner->check_only_first_match() &&
+ !join_tab->first_inner)
+ return TRUE;
+ /*
+ This is the first match for the outer table row.
+ The function set_match_flag_if_none has turned the flag
+ first_inner->found on. The pushdown predicates for
+ inner tables must be re-evaluated with this flag on.
+ Note that, if first_inner is the first inner table
+ of a semi-join, but is not an inner table of an outer join
+ such that 'not exists' optimization can be applied to it,
+ the re-evaluation of the pushdown predicates is not needed.
+ */
+ for (JOIN_TAB *tab= first_inner; tab <= join_tab; tab++)
+ {
+ if (tab->select && tab->select->skip_record(join->thd) <= 0)
+ return FALSE;
+ }
+ }
+ while ((first_inner= first_inner->first_upper) &&
+ first_inner->last_inner == join_tab);
+
+ return TRUE;
+}
+
+
+/*
+ Add null complements for unmatched outer records from join buffer
+
+ SYNOPSIS
+ join_null_complements()
+ skip_last do not add null complements for the last record
+
+ DESCRIPTION
+ This function is called only for inner tables of outer joins.
+ The function retrieves all rows from the join buffer and adds null
+ complements for those of them that do not have matches for outer
+ table records.
+ If the 'join_tab' is the last inner table of the embedding outer
+ join and the null complemented record satisfies the outer join
+ condition then the the corresponding match flag is turned on
+ unless it has been set earlier. This setting may trigger
+ re-evaluation of pushdown conditions for the record.
+
+ NOTES
+ The same implementation of the virtual method join_null_complements
+ is used for BNL/BNLH/BKA/BKA join algorthm.
+
+ RETURN VALUE
+ return one of enum_nested_loop_state.
+*/
+
+enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
+{
+ uint cnt;
+ enum_nested_loop_state rc= NESTED_LOOP_OK;
+ bool is_first_inner= join_tab == join_tab->first_unmatched;
+
+ /* Return at once if there are no records in the join buffer */
+ if (!records)
+ return NESTED_LOOP_OK;
+
+ cnt= records - (is_key_access() ? 0 : test(skip_last));
+
+ /* This function may be called only for inner tables of outer joins */
+ DBUG_ASSERT(join_tab->first_inner);
+
+ for ( ; cnt; cnt--)
+ {
+ if (join->thd->killed)
+ {
+ /* The user has aborted the execution of the query */
+ join->thd->send_kill_message();
+ rc= NESTED_LOOP_KILLED;
+ goto finish;
+ }
+ /* Just skip the whole record if a match for it has been already found */
+ if (!is_first_inner || !skip_if_matched())
+ {
+ get_record();
+ /* The outer row is complemented by nulls for each inner table */
+ restore_record(join_tab->table, s->default_values);
+ mark_as_null_row(join_tab->table);
+ rc= generate_full_extensions(get_curr_rec());
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
+ goto finish;
+ }
+ }
+
+finish:
+ return rc;
+}
+
+
+/*
+ Add a comment on the join algorithm employed by the join cache
+
+ SYNOPSIS
+ print_explain_comment()
+ str string to add the comment on the employed join algorithm to
+
+ DESCRIPTION
+ This function adds info on the type of the used join buffer (flat or
+ incremental) and on the type of the the employed join algorithm (BNL,
+ BNLH, BKA or BKAH) to the the end of the sring str.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE::print_explain_comment(String *str)
+{
+ str->append(STRING_WITH_LEN(" ("));
+ const char *buffer_type= prev_cache ? "incremental" : "flat";
+ str->append(buffer_type);
+ str->append(STRING_WITH_LEN(", "));
+
+ const char *join_alg="";
+ switch (get_join_alg()) {
+ case BNL_JOIN_ALG:
+ join_alg= "BNL";
+ break;
+ case BNLH_JOIN_ALG:
+ join_alg= "BNLH";
+ break;
+ case BKA_JOIN_ALG:
+ join_alg= "BKA";
+ break;
+ case BKAH_JOIN_ALG:
+ join_alg= "BKAH";
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+
+ str->append(join_alg);
+ str->append(STRING_WITH_LEN(" join"));
+ str->append(STRING_WITH_LEN(")"));
+ }
+
+
+/*
+ Initialize a hashed join cache
+
+ SYNOPSIS
+ init()
+
+ DESCRIPTION
+ The function initializes the cache structure with a hash table in it.
+ The hash table will be used to store key values for the records from
+ the join buffer.
+ The function allocates memory for the join buffer and for descriptors of
+ the record fields stored in the buffer.
+ The function also initializes a hash table for record keys within the join
+ buffer space.
+
+ NOTES VALUE
+ The function is supposed to be called by the init methods of the classes
+ derived from JOIN_CACHE_HASHED.
+
+ RETURN VALUE
+ 0 initialization with buffer allocations has been succeeded
+ 1 otherwise
+*/
+
+int JOIN_CACHE_HASHED::init()
+{
+ int rc= 0;
+ TABLE_REF *ref= &join_tab->ref;
+
+ DBUG_ENTER("JOIN_CACHE_HASHED::init");
+
+ hash_table= 0;
+ key_entries= 0;
+
+ key_length= ref->key_length;
+
+ if ((rc= JOIN_CACHE::init()))
+ DBUG_RETURN (rc);
+
+ if (!(key_buff= (uchar*) sql_alloc(key_length)))
+ DBUG_RETURN(1);
+
+ /* Take into account a reference to the next record in the key chain */
+ pack_length+= get_size_of_rec_offset();
+ pack_length_with_blob_ptrs+= get_size_of_rec_offset();
+
+ ref_key_info= join_tab->table->key_info+join_tab->ref.key;
+ ref_used_key_parts= join_tab->ref.key_parts;
+
+ hash_func= &JOIN_CACHE_HASHED::get_hash_idx_simple;
+ hash_cmp_func= &JOIN_CACHE_HASHED::equal_keys_simple;
+
+ KEY_PART_INFO *key_part= ref_key_info->key_part;
+ KEY_PART_INFO *key_part_end= key_part+ref_used_key_parts;
+ for ( ; key_part < key_part_end; key_part++)
+ {
+ if (!key_part->field->eq_cmp_as_binary())
+ {
+ hash_func= &JOIN_CACHE_HASHED::get_hash_idx_complex;
+ hash_cmp_func= &JOIN_CACHE_HASHED::equal_keys_complex;
+ break;
+ }
+ }
+
+ init_hash_table();
+
+ rec_fields_offset= get_size_of_rec_offset()+get_size_of_rec_length()+
+ (prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
+
+ data_fields_offset= 0;
+ if (use_emb_key)
+ {
+ CACHE_FIELD *copy= field_descr;
+ CACHE_FIELD *copy_end= copy+flag_fields;
+ for ( ; copy < copy_end; copy++)
+ data_fields_offset+= copy->length;
+ }
+
+ DBUG_RETURN(rc);
+}
+
+
+/*
+ Initialize the hash table of a hashed join cache
+
+ SYNOPSIS
+ init_hash_table()
+
+ DESCRIPTION
+ The function estimates the number of hash table entries in the hash
+ table to be used and initializes this hash table within the join buffer
+ space.
+
+ RETURN VALUE
+ Currently the function always returns 0;
+*/
+
+int JOIN_CACHE_HASHED::init_hash_table()
+{
+ hash_table= 0;
+ key_entries= 0;
+
+ /* Calculate the minimal possible value of size_of_key_ofs greater than 1 */
+ uint max_size_of_key_ofs= max(2, get_size_of_rec_offset());
+ for (size_of_key_ofs= 2;
+ size_of_key_ofs <= max_size_of_key_ofs;
+ size_of_key_ofs+= 2)
+ {
+ key_entry_length= get_size_of_rec_offset() + // key chain header
+ size_of_key_ofs + // reference to the next key
+ (use_emb_key ? get_size_of_rec_offset() : key_length);
+
+ ulong space_per_rec= avg_record_length +
+ avg_aux_buffer_incr +
+ key_entry_length+size_of_key_ofs;
+ uint n= buff_size / space_per_rec;
+
+ /*
+ TODO: Make a better estimate for this upper bound of
+ the number of records in in the join buffer.
+ */
+ uint max_n= buff_size / (pack_length-length+
+ key_entry_length+size_of_key_ofs);
+
+ hash_entries= (uint) (n / 0.7);
+ set_if_bigger(hash_entries, 1);
+
+ if (offset_size(max_n*key_entry_length) <=
+ size_of_key_ofs)
+ break;
+ }
+
+ /* Initialize the hash table */
+ hash_table= buff + (buff_size-hash_entries*size_of_key_ofs);
+ cleanup_hash_table();
+ curr_key_entry= hash_table;
+
+ return 0;
+}
+
+
+/*
+ Reallocate the join buffer of a hashed join cache
+
+ SYNOPSIS
+ realloc_buffer()
+
+ DESCRITION
+ The function reallocates the join buffer of the hashed join cache.
+ After this it initializes a hash table within the buffer space and
+ resets the join cache for writing.
+
+ NOTES
+ The function assumes that buff_size contains the new value for the join
+ buffer size.
+
+ RETURN VALUE
+ 0 if the buffer has been successfully reallocated
+ 1 otherwise
+*/
+
+int JOIN_CACHE_HASHED::realloc_buffer()
+{
+ int rc;
+ free();
+ rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(0))));
+ init_hash_table();
+ reset(TRUE);
+ return rc;
+}
+
+
+/*
+ Get maximum size of the additional space per record used for record keys
+
+ SYNOPSYS
+ get_max_key_addon_space_per_record()
+
+ DESCRIPTION
+ The function returns the size of the space occupied by one key entry
+ and one hash table entry.
+
+ RETURN VALUE
+ maximum size of the additional space per record that is used to store
+ record keys in the hash table
+*/
+
+uint JOIN_CACHE_HASHED::get_max_key_addon_space_per_record()
+{
+ ulong len;
+ TABLE_REF *ref= &join_tab->ref;
+ /*
+ The total number of hash entries in the hash tables is bounded by
+ ceiling(N/0.7) where N is the maximum number of records in the buffer.
+ That's why the multiplier 2 is used in the formula below.
+ */
+ len= (use_emb_key ? get_size_of_rec_offset() : ref->key_length) +
+ size_of_rec_ofs + // size of the key chain header
+ size_of_rec_ofs + // >= size of the reference to the next key
+ 2*size_of_rec_ofs; // >= 2*( size of hash table entry)
+ return len;
+}
+
+
+/*
+ Reset the buffer of a hashed join cache for reading/writing
+
+ SYNOPSIS
+ reset()
+ for_writing if it's TRUE the function reset the buffer for writing
+
+ DESCRIPTION
+ This implementation of the virtual function reset() resets the join buffer
+ of the JOIN_CACHE_HASHED class for reading or writing.
+ Additionally to what the default implementation does this function
+ cleans up the hash table allocated within the buffer.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE_HASHED::reset(bool for_writing)
+{
+ this->JOIN_CACHE::reset(for_writing);
+ if (for_writing && hash_table)
+ cleanup_hash_table();
+ curr_key_entry= hash_table;
+}
+
+
+/*
+ Add a record into the buffer of a hashed join cache
+
+ SYNOPSIS
+ put_record()
+
+ DESCRIPTION
+ This implementation of the virtual function put_record writes the next
+ matching record into the join buffer of the JOIN_CACHE_HASHED class.
+ Additionally to what the default implementation does this function
+ performs the following.
+ It extracts from the record the key value used in lookups for matching
+ records and searches for this key in the hash tables from the join cache.
+ If it finds the key in the hash table it joins the record to the chain
+ of records with this key. If the key is not found in the hash table the
+ key is placed into it and a chain containing only the newly added record
+ is attached to the key entry. The key value is either placed in the hash
+ element added for the key or, if the use_emb_key flag is set, remains in
+ the record from the partial join.
+ If the match flag field of a record contains MATCH_IMPOSSIBLE the key is
+ not created for this record.
+
+ RETURN VALUE
+ TRUE if it has been decided that it should be the last record
+ in the join buffer,
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_HASHED::put_record()
+{
+ bool is_full;
+ uchar *key;
+ uint key_len= key_length;
+ uchar *key_ref_ptr;
+ uchar *link= 0;
+ TABLE_REF *ref= &join_tab->ref;
+ uchar *next_ref_ptr= pos;
+
+ pos+= get_size_of_rec_offset();
+ /* Write the record into the join buffer */
+ if (prev_cache)
+ link= prev_cache->get_curr_rec_link();
+ write_record_data(link, &is_full);
+
+ if (last_written_is_null_compl)
+ return is_full;
+
+ if (use_emb_key)
+ key= get_curr_emb_key();
+ else
+ {
+ /* Build the key over the fields read into the record buffers */
+ cp_buffer_from_ref(join->thd, join_tab->table, ref);
+ key= ref->key_buff;
+ }
+
+ /* Look for the key in the hash table */
+ if (key_search(key, key_len, &key_ref_ptr))
+ {
+ uchar *last_next_ref_ptr;
+ /*
+ The key is found in the hash table.
+ Add the record to the circular list of the records attached to this key.
+ Below 'rec' is the record to be added into the record chain for the found
+ key, 'key_ref' points to a flatten representation of the st_key_entry
+ structure that contains the key and the head of the record chain.
+ */
+ last_next_ref_ptr= get_next_rec_ref(key_ref_ptr+get_size_of_key_offset());
+ /* rec->next_rec= key_entry->last_rec->next_rec */
+ memcpy(next_ref_ptr, last_next_ref_ptr, get_size_of_rec_offset());
+ /* key_entry->last_rec->next_rec= rec */
+ store_next_rec_ref(last_next_ref_ptr, next_ref_ptr);
+ /* key_entry->last_rec= rec */
+ store_next_rec_ref(key_ref_ptr+get_size_of_key_offset(), next_ref_ptr);
+ }
+ else
+ {
+ /*
+ The key is not found in the hash table.
+ Put the key into the join buffer linking it with the keys for the
+ corresponding hash entry. Create a circular list with one element
+ referencing the record and attach the list to the key in the buffer.
+ */
+ uchar *cp= last_key_entry;
+ cp-= get_size_of_rec_offset()+get_size_of_key_offset();
+ store_next_key_ref(key_ref_ptr, cp);
+ store_null_key_ref(cp);
+ store_next_rec_ref(next_ref_ptr, next_ref_ptr);
+ store_next_rec_ref(cp+get_size_of_key_offset(), next_ref_ptr);
+ if (use_emb_key)
+ {
+ cp-= get_size_of_rec_offset();
+ store_emb_key_ref(cp, key);
+ }
+ else
+ {
+ cp-= key_len;
+ memcpy(cp, key, key_len);
+ }
+ last_key_entry= cp;
+ DBUG_ASSERT(last_key_entry >= end_pos);
+ /* Increment the counter of key_entries in the hash table */
+ key_entries++;
+ }
+ return is_full;
+}
+
+
+/*
+ Read the next record from the buffer of a hashed join cache
+
+ SYNOPSIS
+ get_record()
+
+ DESCRIPTION
+ Additionally to what the default implementation of the virtual
+ function get_record does this implementation skips the link element
+ used to connect the records with the same key into a chain.
+
+ RETURN VALUE
+ TRUE there are no more records to read from the join buffer
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_HASHED::get_record()
+{
+ pos+= get_size_of_rec_offset();
+ return this->JOIN_CACHE::get_record();
+}
+
+
+/*
+ Skip record from a hashed join buffer if its match flag is set to MATCH_FOUND
+
+ SYNOPSIS
+ skip_if_matched()
+
+ DESCRIPTION
+ This implementation of the virtual function skip_if_matched does
+ the same as the default implementation does, but it takes into account
+ the link element used to connect the records with the same key into a chain.
+
+ RETURN VALUE
+ TRUE the match flag is MATCH_FOUND and the record has been skipped
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_HASHED::skip_if_matched()
+{
+ uchar *save_pos= pos;
+ pos+= get_size_of_rec_offset();
+ if (!this->JOIN_CACHE::skip_if_matched())
+ {
+ pos= save_pos;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ Skip record from a hashed join buffer if its match flag dictates to do so
+
+ SYNOPSIS
+ skip_if_uneeded_match()
+
+ DESCRIPTION
+ This implementation of the virtual function skip_if_not_needed_match does
+ the same as the default implementation does, but it takes into account
+ the link element used to connect the records with the same key into a chain.
+
+ RETURN VALUE
+ TRUE the match flag dictates to skip the record
+ FALSE the match flag is off
+*/
+
+bool JOIN_CACHE_HASHED::skip_if_not_needed_match()
+{
+ uchar *save_pos= pos;
+ pos+= get_size_of_rec_offset();
+ if (!this->JOIN_CACHE::skip_if_not_needed_match())
+ {
+ pos= save_pos;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ Search for a key in the hash table of the join buffer
+
+ SYNOPSIS
+ key_search()
+ key pointer to the key value
+ key_len key value length
+ key_ref_ptr OUT position of the reference to the next key from
+ the hash element for the found key , or
+ a position where the reference to the the hash
+ element for the key is to be added in the
+ case when the key has not been found
+
+ DESCRIPTION
+ The function looks for a key in the hash table of the join buffer.
+ If the key is found the functionreturns the position of the reference
+ to the next key from to the hash element for the given key.
+ Otherwise the function returns the position where the reference to the
+ newly created hash element for the given key is to be added.
+
+ RETURN VALUE
+ TRUE the key is found in the hash table
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_HASHED::key_search(uchar *key, uint key_len,
+ uchar **key_ref_ptr)
+{
+ bool is_found= FALSE;
+ uint idx= (this->*hash_func)(key, key_length);
+ uchar *ref_ptr= hash_table+size_of_key_ofs*idx;
+ while (!is_null_key_ref(ref_ptr))
+ {
+ uchar *next_key;
+ ref_ptr= get_next_key_ref(ref_ptr);
+ next_key= use_emb_key ? get_emb_key(ref_ptr-get_size_of_rec_offset()) :
+ ref_ptr-key_length;
+
+ if ((this->*hash_cmp_func)(next_key, key, key_len))
+ {
+ is_found= TRUE;
+ break;
+ }
+ }
+ *key_ref_ptr= ref_ptr;
+ return is_found;
+}
+
+
+/*
+ Hash function that considers a key in the hash table as byte array
+
+ SYNOPSIS
+ get_hash_idx_simple()
+ key pointer to the key value
+ key_len key value length
+
+ DESCRIPTION
+ The function calculates an index of the hash entry in the hash table
+ of the join buffer for the given key. It considers the key just as
+ a sequence of bytes of the length key_len.
+
+ RETURN VALUE
+ the calculated index of the hash entry for the given key
+*/
+
+inline
+uint JOIN_CACHE_HASHED::get_hash_idx_simple(uchar* key, uint key_len)
+{
+ ulong nr= 1;
+ ulong nr2= 4;
+ uchar *pos= key;
+ uchar *end= key+key_len;
+ for (; pos < end ; pos++)
+ {
+ nr^= (ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
+ nr2+= 3;
+ }
+ return nr % hash_entries;
+}
+
+
+/*
+ Hash function that takes into account collations of the components of the key
+
+ SYNOPSIS
+ get_hash_idx_complex()
+ key pointer to the key value
+ key_len key value length
+
+ DESCRIPTION
+ The function calculates an index of the hash entry in the hash table
+ of the join buffer for the given key. It takes into account that the
+ components of the key may be of a varchar type with different collations.
+ The function guarantees that the same hash value for any two equal
+ keys that may differ as byte sequences.
+ The function takes the info about the components of the key, their
+ types and used collations from the class member ref_key_info containing
+ a pointer to the descriptor of the index that can be used for the join
+ operation.
+
+ RETURN VALUE
+ the calculated index of the hash entry for the given key
+*/
+
+inline
+uint JOIN_CACHE_HASHED::get_hash_idx_complex(uchar *key, uint key_len)
+{
+ return
+ (uint) (key_hashnr(ref_key_info, ref_used_key_parts, key) % hash_entries);
+}
+
+
+/*
+ Compare two key entries in the hash table as sequence of bytes
+
+ SYNOPSIS
+ equal_keys_simple()
+ key1 pointer to the first key entry
+ key2 pointer to the second key entry
+ key_len the length of the key values
+
+ DESCRIPTION
+ The function compares two key entries in the hash table key1 and key2
+ as two sequences bytes of the length key_len
+
+ RETURN VALUE
+ TRUE key1 coincides with key2
+ FALSE otherwise
+*/
+
+inline
+bool JOIN_CACHE_HASHED::equal_keys_simple(uchar *key1, uchar *key2,
+ uint key_len)
+{
+ return memcmp(key1, key2, key_len) == 0;
+}
+
+
+/*
+ Compare two key entries taking into account the used collation
+
+ SYNOPSIS
+ equal_keys_complex()
+ key1 pointer to the first key entry
+ key2 pointer to the second key entry
+ key_len the length of the key values
+
+ DESCRIPTION
+ The function checks whether two key entries in the hash table
+ key1 and key2 are equal as, possibly, compound keys of a certain
+ structure whose components may be of a varchar type and may
+ employ different collations.
+ The descriptor of the key structure is taken from the class
+ member ref_key_info.
+
+ RETURN VALUE
+ TRUE key1 is equal tokey2
+ FALSE otherwise
+*/
+
+inline
+bool JOIN_CACHE_HASHED::equal_keys_complex(uchar *key1, uchar *key2,
+ uint key_len)
+{
+ return key_buf_cmp(ref_key_info, ref_used_key_parts, key1, key2) == 0;
+}
+
+
+/*
+ Clean up the hash table of the join buffer
+
+ SYNOPSIS
+ cleanup_hash_table()
+ key pointer to the key value
+ key_len key value length
+
+ DESCRIPTION
+ The function cleans up the hash table in the join buffer removing all
+ hash elements from the table.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE_HASHED:: cleanup_hash_table()
+{
+ last_key_entry= hash_table;
+ bzero(hash_table, (buff+buff_size)-hash_table);
+ key_entries= 0;
+}
+
+
+/*
+ Check whether all records in a key chain have their match flags set on
+
+ SYNOPSIS
+ check_all_match_flags_for_key()
+ key_chain_ptr
+
+ DESCRIPTION
+ This function retrieves records in the given circular chain and checks
+ whether their match flags are set on. The parameter key_chain_ptr shall
+ point to the position in the join buffer storing the reference to the
+ last element of this chain.
+
+ RETURN VALUE
+ TRUE if each retrieved record has its match flag set to MATCH_FOUND
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_HASHED::check_all_match_flags_for_key(uchar *key_chain_ptr)
+{
+ uchar *last_rec_ref_ptr= get_next_rec_ref(key_chain_ptr);
+ uchar *next_rec_ref_ptr= last_rec_ref_ptr;
+ do
+ {
+ next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
+ uchar *rec_ptr= next_rec_ref_ptr+rec_fields_offset;
+ if (get_match_flag_by_pos(rec_ptr) != MATCH_FOUND)
+ return FALSE;
+ }
+ while (next_rec_ref_ptr != last_rec_ref_ptr);
+ return TRUE;
+}
+
+
+/*
+ Get the next key built for the records from the buffer of a hashed join cache
+
+ SYNOPSIS
+ get_next_key()
+ key pointer to the buffer where the key value is to be placed
+
+ DESCRIPTION
+ The function reads the next key value stored in the hash table of the
+ join buffer. Depending on the value of the use_emb_key flag of the
+ join cache the value is read either from the table itself or from
+ the record field where it occurs.
+
+ RETURN VALUE
+ length of the key value - if the starting value of 'cur_key_entry' refers
+ to the position after that referred by the the value of 'last_key_entry',
+ 0 - otherwise.
+*/
+
+uint JOIN_CACHE_HASHED::get_next_key(uchar ** key)
+{
+ if (curr_key_entry == last_key_entry)
+ return 0;
+
+ curr_key_entry-= key_entry_length;
+
+ *key = use_emb_key ? get_emb_key(curr_key_entry) : curr_key_entry;
+
+ DBUG_ASSERT(*key >= buff && *key < hash_table);
+
+ return key_length;
+}
+
+
+/*
+ Initiate an iteration process over records in the joined table
+
+ SYNOPSIS
+ open()
+
+ DESCRIPTION
+ The function initiates the process of iteration over records from the
+ joined table recurrently performed by the BNL/BKLH join algorithm.
+
+ RETURN VALUE
+ 0 the initiation is a success
+ error code otherwise
+*/
+
+int JOIN_TAB_SCAN::open()
+{
+ for (JOIN_TAB *tab= join->join_tab; tab != join_tab ; tab++)
+ {
+ tab->status= tab->table->status;
+ tab->table->status= 0;
+ }
+ is_first_record= TRUE;
+ return join_init_read_record(join_tab);
+}
+
+
+/*
+ Read the next record that can match while scanning the joined table
+
+ SYNOPSIS
+ next()
+
+ DESCRIPTION
+ The function reads the next record from the joined table that can
+ match some records in the buffer of the join cache 'cache'. To do
+ this the function calls the function that scans table records and
+ looks for the next one that meets the condition pushed to the
+ joined table join_tab.
+
+ NOTES
+ The function catches the signal that kills the query.
+
+ RETURN VALUE
+ 0 the next record exists and has been successfully read
+ error code otherwise
+*/
+
+int JOIN_TAB_SCAN::next()
+{
+ int err= 0;
+ int skip_rc;
+ READ_RECORD *info= &join_tab->read_record;
+ SQL_SELECT *select= join_tab->cache_select;
+ if (is_first_record)
+ is_first_record= FALSE;
+ else
+ err= info->read_record(info);
+ if (!err)
+ update_virtual_fields(join->thd, join_tab->table);
+ while (!err && select && (skip_rc= select->skip_record(join->thd)) <= 0)
+ {
+ if (join->thd->killed || skip_rc < 0)
+ return 1;
+ /*
+ Move to the next record if the last retrieved record does not
+ meet the condition pushed to the table join_tab.
+ */
+ err= info->read_record(info);
+ if (!err)
+ update_virtual_fields(join->thd, join_tab->table);
+ }
+ return err;
+}
+
+
+/*
+ Perform finalizing actions for a scan over the table records
+
+ SYNOPSIS
+ close()
+
+ DESCRIPTION
+ The function performs the necessary restoring actions after
+ the table scan over the joined table has been finished.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_TAB_SCAN::close()
+{
+ for (JOIN_TAB *tab= join->join_tab; tab != join_tab ; tab++)
+ tab->table->status= tab->status;
+}
+
+
+/*
+ Prepare to iterate over the BNL join cache buffer to look for matches
+
+ SYNOPSIS
+ prepare_look_for_matches()
+ skip_last <-> ignore the last record in the buffer
+
+ DESCRIPTION
+ The function prepares the join cache for an iteration over the
+ records in the join buffer. The iteration is performed when looking
+ for matches for the record from the joined table join_tab that
+ has been placed into the record buffer of the joined table.
+ If the value of the parameter skip_last is TRUE then the last
+ record from the join buffer is ignored.
+ The function initializes the counter of the records that have been
+ not iterated over yet.
+
+ RETURN VALUE
+ TRUE there are no records in the buffer to iterate over
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BNL::prepare_look_for_matches(bool skip_last)
+{
+ if (!records)
+ return TRUE;
+ reset(FALSE);
+ rem_records= records-test(skip_last);
+ return rem_records == 0;
+}
+
+
+/*
+ Get next record from the BNL join cache buffer when looking for matches
+
+ SYNOPSIS
+ get_next_candidate_for_match
+
+ DESCRIPTION
+ This method is used for iterations over the records from the join
+ cache buffer when looking for matches for records from join_tab.
+ The methods performs the necessary preparations to read the next record
+ from the join buffer into the record buffer by the method
+ read_next_candidate_for_match, or, to skip the next record from the join
+ buffer by the method skip_recurrent_candidate_for_match.
+ This implementation of the virtual method get_next_candidate_for_match
+ just decrements the counter of the records that are to be iterated over
+ and returns the current value of the cursor 'pos' as the position of
+ the record to be processed.
+
+ RETURN VALUE
+ pointer to the position right after the prefix of the current record
+ in the join buffer if the there is another record to iterate over,
+ 0 - otherwise.
+*/
+
+uchar *JOIN_CACHE_BNL::get_next_candidate_for_match()
+{
+ if (!rem_records)
+ return 0;
+ rem_records--;
+ return pos+base_prefix_length;
+}
+
+
+/*
+ Check whether the matching record from the BNL cache is to be skipped
+
+ SYNOPSIS
+ skip_next_candidate_for_match
+ rec_ptr pointer to the position in the join buffer right after the prefix
+ of the current record
+
+ DESCRIPTION
+ This implementation of the virtual function just calls the
+ method skip_if_not_needed_match to check whether the record referenced by
+ ref_ptr has its match flag set either to MATCH_FOUND and join_tab is the
+ first inner table of a semi-join, or it's set to MATCH_IMPOSSIBLE and
+ join_tab is the first inner table of an outer join.
+ If so, the function just skips this record setting the value of the
+ cursor 'pos' to the position right after it.
+
+ RETURN VALUE
+ TRUE the record referenced by rec_ptr has been skipped
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BNL::skip_next_candidate_for_match(uchar *rec_ptr)
+{
+ pos= rec_ptr-base_prefix_length;
+ return skip_if_not_needed_match();
+}
+
+
+/*
+ Read next record from the BNL join cache buffer when looking for matches
+
+ SYNOPSIS
+ read_next_candidate_for_match
+ rec_ptr pointer to the position in the join buffer right after the prefix
+ the current record.
+
+ DESCRIPTION
+ This implementation of the virtual method read_next_candidate_for_match
+ calls the method get_record to read the record referenced by rec_ptr from
+ the join buffer into the record buffer. If this record refers to the
+ fields in the other join buffers the call of get_record ensures that
+ these fields are read into the corresponding record buffers as well.
+ This function is supposed to be called after a successful call of
+ the method get_next_candidate_for_match.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE_BNL::read_next_candidate_for_match(uchar *rec_ptr)
+{
+ pos= rec_ptr-base_prefix_length;
+ get_record();
+}
+
+
+/*
+ Initialize the BNL join cache
+
+ SYNOPSIS
+ init
+
+ DESCRIPTION
+ The function initializes the cache structure. It is supposed to be called
+ right after a constructor for the JOIN_CACHE_BNL.
+
+ NOTES
+ The function first constructs a companion object of the type JOIN_TAB_SCAN,
+ then it calls the init method of the parent class.
+
+ RETURN VALUE
+ 0 initialization with buffer allocations has been succeeded
+ 1 otherwise
+*/
+
+int JOIN_CACHE_BNL::init()
+{
+ DBUG_ENTER("JOIN_CACHE_BNL::init");
+
+ if (!(join_tab_scan= new JOIN_TAB_SCAN(join, join_tab)))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(JOIN_CACHE::init());
+}
+
+
+/*
+ Get the chain of records from buffer matching the current candidate for join
+
+ SYNOPSIS
+ get_matching_chain_by_join_key()
+
+ DESCRIPTION
+ This function first build a join key for the record of join_tab that
+ currently is in the join buffer for this table. Then it looks for
+ the key entry with this key in the hash table of the join cache.
+ If such a key entry is found the function returns the pointer to
+ the head of the chain of records in the join_buffer that match this
+ key.
+
+ RETURN VALUE
+ The pointer to the corresponding circular list of records if
+ the key entry with the join key is found, 0 - otherwise.
+*/
+
+uchar *JOIN_CACHE_BNLH::get_matching_chain_by_join_key()
+{
+ uchar *key_ref_ptr;
+ TABLE *table= join_tab->table;
+ TABLE_REF *ref= &join_tab->ref;
+ KEY *keyinfo= table->key_info+ref->key;
+ /* Build the join key value out of the record in the record buffer */
+ key_copy(key_buff, table->record[0], keyinfo, key_length);
+ /* Look for this key in the join buffer */
+ if (!key_search(key_buff, key_length, &key_ref_ptr))
+ return 0;
+ return key_ref_ptr+get_size_of_key_offset();
+}
+
+
+/*
+ Prepare to iterate over the BNLH join cache buffer to look for matches
+
+ SYNOPSIS
+ prepare_look_for_matches()
+ skip_last <-> ignore the last record in the buffer
+
+ DESCRIPTION
+ The function prepares the join cache for an iteration over the
+ records in the join buffer. The iteration is performed when looking
+ for matches for the record from the joined table join_tab that
+ has been placed into the record buffer of the joined table.
+ If the value of the parameter skip_last is TRUE then the last
+ record from the join buffer is ignored.
+ The function builds the hashed key from the join fields of join_tab
+ and uses this key to look in the hash table of the join cache for
+ the chain of matching records in in the join buffer. If it finds
+ such a chain it sets the member last_rec_ref_ptr to point to the
+ last link of the chain while setting the member next_rec_ref_po 0.
+
+ RETURN VALUE
+ TRUE there are no matching records in the buffer to iterate over
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BNLH::prepare_look_for_matches(bool skip_last)
+{
+ uchar *curr_matching_chain;
+ last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0;
+ if (!(curr_matching_chain= get_matching_chain_by_join_key()))
+ return 1;
+ last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain);
+ return 0;
+}
+
+
+/*
+ Get next record from the BNLH join cache buffer when looking for matches
+
+ SYNOPSIS
+ get_next_candidate_for_match
+
+ DESCRIPTION
+ This method is used for iterations over the records from the join
+ cache buffer when looking for matches for records from join_tab.
+ The methods performs the necessary preparations to read the next record
+ from the join buffer into the record buffer by the method
+ read_next_candidate_for_match, or, to skip the next record from the join
+ buffer by the method skip_next_candidate_for_match.
+ This implementation of the virtual method moves to the next record
+ in the chain of all records from the join buffer that are to be
+ equi-joined with the current record from join_tab.
+
+ RETURN VALUE
+ pointer to the beginning of the record fields in the join buffer
+ if the there is another record to iterate over, 0 - otherwise.
+*/
+
+uchar *JOIN_CACHE_BNLH::get_next_candidate_for_match()
+{
+ if (next_matching_rec_ref_ptr == last_matching_rec_ref_ptr)
+ return 0;
+ next_matching_rec_ref_ptr= get_next_rec_ref(next_matching_rec_ref_ptr ?
+ next_matching_rec_ref_ptr :
+ last_matching_rec_ref_ptr);
+ return next_matching_rec_ref_ptr+rec_fields_offset;
+}
+
+
+/*
+ Check whether the matching record from the BNLH cache is to be skipped
+
+ SYNOPSIS
+ skip_next_candidate_for_match
+ rec_ptr pointer to the position in the join buffer right after
+ the previous record
+
+ DESCRIPTION
+ This implementation of the virtual function just calls the
+ method get_match_flag_by_pos to check whether the record referenced
+ by ref_ptr has its match flag set to MATCH_FOUND.
+
+ RETURN VALUE
+ TRUE the record referenced by rec_ptr has its match flag set to
+ MATCH_FOUND
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BNLH::skip_next_candidate_for_match(uchar *rec_ptr)
+{
+ return join_tab->check_only_first_match() &&
+ (get_match_flag_by_pos(rec_ptr) == MATCH_FOUND);
+}
+
+
+/*
+ Read next record from the BNLH join cache buffer when looking for matches
+
+ SYNOPSIS
+ read_next_candidate_for_match
+ rec_ptr pointer to the position in the join buffer right after
+ the previous record
+
+ DESCRIPTION
+ This implementation of the virtual method read_next_candidate_for_match
+ calls the method get_record_by_pos to read the record referenced by rec_ptr
+ from the join buffer into the record buffer. If this record refers to
+ fields in the other join buffers the call of get_record_by_po ensures that
+ these fields are read into the corresponding record buffers as well.
+ This function is supposed to be called after a successful call of
+ the method get_next_candidate_for_match.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE_BNLH::read_next_candidate_for_match(uchar *rec_ptr)
+{
+ get_record_by_pos(rec_ptr);
+}
+
+
+/*
+ Initialize the BNLH join cache
+
+ SYNOPSIS
+ init
+
+ DESCRIPTION
+ The function initializes the cache structure. It is supposed to be called
+ right after a constructor for the JOIN_CACHE_BNLH.
+
+ NOTES
+ The function first constructs a companion object of the type JOIN_TAB_SCAN,
+ then it calls the init method of the parent class.
+
+ RETURN VALUE
+ 0 initialization with buffer allocations has been succeeded
+ 1 otherwise
+*/
+
+int JOIN_CACHE_BNLH::init()
+{
+ DBUG_ENTER("JOIN_CACHE_BNLH::init");
+
+ if (!(join_tab_scan= new JOIN_TAB_SCAN(join, join_tab)))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(JOIN_CACHE_HASHED::init());
+}
+
+
+/*
+ Calculate the increment of the MRR buffer for a record write
+
+ SYNOPSIS
+ aux_buffer_incr()
+
+ DESCRIPTION
+ This implementation of the virtual function aux_buffer_incr determines
+ for how much the size of the MRR buffer should be increased when another
+ record is added to the cache.
+
+ RETURN VALUE
+ the increment of the size of the MRR buffer for the next record
+*/
+
+uint JOIN_TAB_SCAN_MRR::aux_buffer_incr(ulong recno)
+{
+ uint incr= 0;
+ TABLE_REF *ref= &join_tab->ref;
+ TABLE *tab= join_tab->table;
+ uint rec_per_key= tab->key_info[ref->key].rec_per_key[ref->key_parts-1];
+ set_if_bigger(rec_per_key, 1);
+ if (recno == 1)
+ incr= ref->key_length + tab->file->ref_length;
+ incr+= tab->file->stats.mrr_length_per_rec * rec_per_key;
+ return incr;
+}
+
+
+/*
+ Initiate iteration over records returned by MRR for the current join buffer
+
+ SYNOPSIS
+ open()
+
+ DESCRIPTION
+ The function initiates the process of iteration over the records from
+ join_tab returned by the MRR interface functions for records from
+ the join buffer. Such an iteration is performed by the BKA/BKAH join
+ algorithm for each new refill of the join buffer.
+ The function calls the MRR handler function multi_range_read_init to
+ initiate this process.
+
+ RETURN VALUE
+ 0 the initiation is a success
+ error code otherwise
+*/
+
+int JOIN_TAB_SCAN_MRR::open()
+{
+ handler *file= join_tab->table->file;
+
+ join_tab->table->null_row= 0;
+
+
+ /* Dynamic range access is never used with BKA */
+ DBUG_ASSERT(join_tab->use_quick != 2);
+
+ for (JOIN_TAB *tab =join->join_tab; tab != join_tab ; tab++)
+ {
+ tab->status= tab->table->status;
+ tab->table->status= 0;
+ }
+
+ init_mrr_buff();
+
+ /*
+ Prepare to iterate over keys from the join buffer and to get
+ matching candidates obtained with MMR handler functions.
+ */
+ if (!file->inited)
+ file->ha_index_init(join_tab->ref.key, 1);
+ ranges= cache->get_number_of_ranges_for_mrr();
+ if (!join_tab->cache_idx_cond)
+ range_seq_funcs.skip_index_tuple= 0;
+ return file->multi_range_read_init(&range_seq_funcs, (void*) cache,
+ ranges, mrr_mode, &mrr_buff);
+}
+
+
+/*
+ Read the next record returned by MRR for the current join buffer
+
+ SYNOPSIS
+ next()
+
+ DESCRIPTION
+ The function reads the next record from the joined table join_tab
+ returned by the MRR handler function multi_range_read_next for
+ the current refill of the join buffer. The record is read into
+ the record buffer used for join_tab records in join operations.
+
+ RETURN VALUE
+ 0 the next record exists and has been successfully read
+ error code otherwise
+*/
+
+int JOIN_TAB_SCAN_MRR::next()
+{
+ char **ptr= (char **) cache->get_curr_association_ptr();
+ int rc= join_tab->table->file->multi_range_read_next(ptr) ? -1 : 0;
+ if (!rc)
+ {
+ /*
+ If a record in in an incremental cache contains no fields then the
+ association for the last record in cache will be equal to cache->end_pos
+ */
+ DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) &&
+ (uchar *) (*ptr) <= cache->end_pos);
+ update_virtual_fields(join->thd, join_tab->table);
+ }
+ return rc;
+}
+
+
+static
+void bka_range_seq_key_info(void *init_params, uint *length,
+ key_part_map *map)
+{
+ TABLE_REF *ref= &(((JOIN_CACHE*)init_params)->join_tab->ref);
+ *length= ref->key_length;
+ *map= (key_part_map(1) << ref->key_parts) - 1;
+}
+
+
+/*
+ Initialize retrieval of range sequence for BKA join algorithm
+
+ SYNOPSIS
+ bka_range_seq_init()
+ init_params pointer to the BKA join cache object
+ n_ranges the number of ranges obtained
+ flags combination of MRR flags
+
+ DESCRIPTION
+ The function interprets init_param as a pointer to a JOIN_CACHE_BKA
+ object. The function prepares for an iteration over the join keys
+ built for all records from the cache join buffer.
+
+ NOTE
+ This function are used only as a callback function.
+
+ RETURN VALUE
+ init_param value that is to be used as a parameter of bka_range_seq_next()
+*/
+
+static
+range_seq_t bka_range_seq_init(void *init_param, uint n_ranges, uint flags)
+{
+ DBUG_ENTER("bka_range_seq_init");
+ JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) init_param;
+ cache->reset(0);
+ DBUG_RETURN((range_seq_t) init_param);
+}
+
+
+/*
+ Get the next range/key over records from the join buffer used by a BKA cache
+
+ SYNOPSIS
+ bka_range_seq_next()
+ seq the value returned by bka_range_seq_init
+ range OUT reference to the next range
+
+ DESCRIPTION
+ The function interprets seq as a pointer to a JOIN_CACHE_BKA
+ object. The function returns a pointer to the range descriptor
+ for the key built over the next record from the join buffer.
+
+ NOTE
+ This function are used only as a callback function.
+
+ RETURN VALUE
+ FALSE ok, the range structure filled with info about the next range/key
+ TRUE no more ranges
+*/
+
+static
+bool bka_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
+{
+ DBUG_ENTER("bka_range_seq_next");
+ JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
+ TABLE_REF *ref= &cache->join_tab->ref;
+ key_range *start_key= &range->start_key;
+ if ((start_key->length= cache->get_next_key((uchar **) &start_key->key)))
+ {
+ start_key->keypart_map= (1 << ref->key_parts) - 1;
+ start_key->flag= HA_READ_KEY_EXACT;
+ range->end_key= *start_key;
+ range->end_key.flag= HA_READ_AFTER_KEY;
+ range->ptr= (char *) cache->get_curr_rec();
+ range->range_flag= EQ_RANGE;
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Check whether range_info orders to skip the next record from BKA buffer
+
+ SYNOPSIS
+ bka_range_seq_skip_record()
+ seq value returned by bka_range_seq_init()
+ range_info information about the next range
+ rowid [NOT USED] rowid of the record to be checked
+
+
+ DESCRIPTION
+ The function interprets seq as a pointer to a JOIN_CACHE_BKA object.
+ The function returns TRUE if the record with this range_info
+ is to be filtered out from the stream of records returned by
+ multi_range_read_next().
+
+ NOTE
+ This function are used only as a callback function.
+
+ RETURN VALUE
+ 1 record with this range_info is to be filtered out from the stream
+ of records returned by multi_range_read_next()
+ 0 the record is to be left in the stream
+*/
+
+static
+bool bka_range_seq_skip_record(range_seq_t rseq, char *range_info, uchar *rowid)
+{
+ DBUG_ENTER("bka_range_seq_skip_record");
+ JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
+ bool res= cache->get_match_flag_by_pos((uchar *) range_info) ==
+ JOIN_CACHE::MATCH_FOUND;
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Check if the record combination from BKA cache matches the index condition
+
+ SYNOPSIS
+ bka_skip_index_tuple()
+ rseq value returned by bka_range_seq_init()
+ range_info record chain for the next range/key returned by MRR
+
+ DESCRIPTION
+ This is wrapper for JOIN_CACHE_BKA::skip_index_tuple method,
+ see comments there.
+
+ NOTE
+ This function is used as a RANGE_SEQ_IF::skip_index_tuple callback.
+
+ RETURN VALUE
+ 0 The record combination satisfies the index condition
+ 1 Otherwise
+*/
+
+static
+bool bka_skip_index_tuple(range_seq_t rseq, char *range_info)
+{
+ DBUG_ENTER("bka_skip_index_tuple");
+ JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
+ DBUG_RETURN(cache->skip_index_tuple(range_info));
+}
+
+
+/*
+ Prepare to read the record from BKA cache matching the current joined record
+
+ SYNOPSIS
+ prepare_look_for_matches()
+ skip_last <-> ignore the last record in the buffer (always unused here)
+
+ DESCRIPTION
+ The function prepares to iterate over records in the join cache buffer
+ matching the record loaded into the record buffer for join_tab when
+ performing join operation by BKA join algorithm. With BKA algorithms the
+ record loaded into the record buffer for join_tab always has a direct
+ reference to the matching records from the join buffer. When the regular
+ BKA join algorithm is employed the record from join_tab can refer to
+ only one such record.
+ The function sets the counter of the remaining records from the cache
+ buffer that would match the current join_tab record to 1.
+
+ RETURN VALUE
+ TRUE there are no records in the buffer to iterate over
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BKA::prepare_look_for_matches(bool skip_last)
+{
+ if (!records)
+ return TRUE;
+ rem_records= 1;
+ return FALSE;
+}
+
+
+/*
+ Get the record from the BKA cache matching the current joined record
+
+ SYNOPSIS
+ get_next_candidate_for_match
+
+ DESCRIPTION
+ This method is used for iterations over the records from the join
+ cache buffer when looking for matches for records from join_tab.
+ The method performs the necessary preparations to read the next record
+ from the join buffer into the record buffer by the method
+ read_next_candidate_for_match, or, to skip the next record from the join
+ buffer by the method skip_if_not_needed_match.
+ This implementation of the virtual method get_next_candidate_for_match
+ just decrements the counter of the records that are to be iterated over
+ and returns the value of curr_association as a reference to the position
+ of the beginning of the record fields in the buffer.
+
+ RETURN VALUE
+ pointer to the start of the record fields in the join buffer
+ if the there is another record to iterate over, 0 - otherwise.
+*/
+
+uchar *JOIN_CACHE_BKA::get_next_candidate_for_match()
+{
+ if (!rem_records)
+ return 0;
+ rem_records--;
+ return curr_association;
+}
+
+
+/*
+ Check whether the matching record from the BKA cache is to be skipped
+
+ SYNOPSIS
+ skip_next_candidate_for_match
+ rec_ptr pointer to the position in the join buffer right after
+ the previous record
+
+ DESCRIPTION
+ This implementation of the virtual function just calls the
+ method get_match_flag_by_pos to check whether the record referenced
+ by ref_ptr has its match flag set to MATCH_FOUND.
+
+ RETURN VALUE
+ TRUE the record referenced by rec_ptr has its match flag set to
+ MATCH_FOUND
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BKA::skip_next_candidate_for_match(uchar *rec_ptr)
+{
+ return join_tab->check_only_first_match() &&
+ (get_match_flag_by_pos(rec_ptr) == MATCH_FOUND);
+}
+
+
+/*
+ Read the next record from the BKA join cache buffer when looking for matches
+
+ SYNOPSIS
+ read_next_candidate_for_match
+ rec_ptr pointer to the position in the join buffer right after
+ the previous record
+
+ DESCRIPTION
+ This implementation of the virtual method read_next_candidate_for_match
+ calls the method get_record_by_pos to read the record referenced by rec_ptr
+ from the join buffer into the record buffer. If this record refers to
+ fields in the other join buffers the call of get_record_by_po ensures that
+ these fields are read into the corresponding record buffers as well.
+ This function is supposed to be called after a successful call of
+ the method get_next_candidate_for_match.
+
+ RETURN VALUE
+ none
+*/
+
+void JOIN_CACHE_BKA::read_next_candidate_for_match(uchar *rec_ptr)
+{
+ get_record_by_pos(rec_ptr);
+}
+
+
+/*
+ Initialize the BKA join cache
+
+ SYNOPSIS
+ init
+
+ DESCRIPTION
+ The function initializes the cache structure. It is supposed to be called
+ right after a constructor for the JOIN_CACHE_BKA.
+
+ NOTES
+ The function first constructs a companion object of the type
+ JOIN_TAB_SCAN_MRR, then it calls the init method of the parent class.
+
+ RETURN VALUE
+ 0 initialization with buffer allocations has been succeeded
+ 1 otherwise
+*/
+
+int JOIN_CACHE_BKA::init()
+{
+ int res;
+ bool check_only_first_match= join_tab->check_only_first_match();
+
+ RANGE_SEQ_IF rs_funcs= { bka_range_seq_key_info,
+ bka_range_seq_init,
+ bka_range_seq_next,
+ check_only_first_match ?
+ bka_range_seq_skip_record : 0,
+ bka_skip_index_tuple };
+
+ DBUG_ENTER("JOIN_CACHE_BKA::init");
+
+ JOIN_TAB_SCAN_MRR *jsm;
+ if (!(join_tab_scan= jsm= new JOIN_TAB_SCAN_MRR(join, join_tab,
+ mrr_mode, rs_funcs)))
+ DBUG_RETURN(1);
+
+ if ((res= JOIN_CACHE::init()))
+ DBUG_RETURN(res);
+
+ if (use_emb_key)
+ jsm->mrr_mode |= HA_MRR_MATERIALIZED_KEYS;
+
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Get the key built over the next record from BKA join buffer
+
+ SYNOPSIS
+ get_next_key()
+ key pointer to the buffer where the key value is to be placed
+
+ DESCRIPTION
+ The function reads key fields from the current record in the join buffer.
+ and builds the key value out of these fields that will be used to access
+ the 'join_tab' table. Some of key fields may belong to previous caches.
+ They are accessed via record references to the record parts stored in the
+ previous join buffers. The other key fields always are placed right after
+ the flag fields of the record.
+ If the key is embedded, which means that its value can be read directly
+ from the join buffer, then *key is set to the beginning of the key in
+ this buffer. Otherwise the key is built in the join_tab->ref->key_buff.
+ The function returns the length of the key if it succeeds ro read it.
+ If is assumed that the functions starts reading at the position of
+ the record length which is provided for each records in a BKA cache.
+ After the key is built the 'pos' value points to the first position after
+ the current record.
+ The function just skips the records with MATCH_IMPOSSIBLE in the
+ match flag field if there is any.
+ The function returns 0 if the initial position is after the beginning
+ of the record fields for last record from the join buffer.
+
+ RETURN VALUE
+ length of the key value - if the starting value of 'pos' points to
+ the position before the fields for the last record,
+ 0 - otherwise.
+*/
+
+uint JOIN_CACHE_BKA::get_next_key(uchar ** key)
+{
+ uint len;
+ uint32 rec_len;
+ uchar *init_pos;
+ JOIN_CACHE *cache;
+
+start:
+
+ /* Any record in a BKA cache is prepended with its length */
+ DBUG_ASSERT(with_length);
+
+ if ((pos+size_of_rec_len) > last_rec_pos || !records)
+ return 0;
+
+ /* Read the length of the record */
+ rec_len= get_rec_length(pos);
+ pos+= size_of_rec_len;
+ init_pos= pos;
+
+ /* Read a reference to the previous cache if any */
+ if (prev_cache)
+ pos+= prev_cache->get_size_of_rec_offset();
+
+ curr_rec_pos= pos;
+
+ /* Read all flag fields of the record */
+ read_flag_fields();
+
+ if (with_match_flag &&
+ (Match_flag) curr_rec_pos[0] == MATCH_IMPOSSIBLE )
+ {
+ pos= init_pos+rec_len;
+ goto start;
+ }
+
+ if (use_emb_key)
+ {
+ /* An embedded key is taken directly from the join buffer */
+ *key= pos;
+ len= emb_key_length;
+ }
+ else
+ {
+ /* Read key arguments from previous caches if there are any such fields */
+ if (external_key_arg_fields)
+ {
+ uchar *rec_ptr= curr_rec_pos;
+ uint key_arg_count= external_key_arg_fields;
+ CACHE_FIELD **copy_ptr= blob_ptr-key_arg_count;
+ for (cache= prev_cache; key_arg_count; cache= cache->prev_cache)
+ {
+ uint len= 0;
+ DBUG_ASSERT(cache);
+ rec_ptr= cache->get_rec_ref(rec_ptr);
+ while (!cache->referenced_fields)
+ {
+ cache= cache->prev_cache;
+ DBUG_ASSERT(cache);
+ rec_ptr= cache->get_rec_ref(rec_ptr);
+ }
+ while (key_arg_count &&
+ cache->read_referenced_field(*copy_ptr, rec_ptr, &len))
+ {
+ copy_ptr++;
+ --key_arg_count;
+ }
+ }
+ }
+
+ /*
+ Read the other key arguments from the current record. The fields for
+ these arguments are always first in the sequence of the record's fields.
+ */
+ CACHE_FIELD *copy= field_descr+flag_fields;
+ CACHE_FIELD *copy_end= copy+local_key_arg_fields;
+ bool blob_in_rec_buff= blob_data_is_in_rec_buff(curr_rec_pos);
+ for ( ; copy < copy_end; copy++)
+ read_record_field(copy, blob_in_rec_buff);
+
+ /* Build the key over the fields read into the record buffers */
+ TABLE_REF *ref= &join_tab->ref;
+ cp_buffer_from_ref(join->thd, join_tab->table, ref);
+ *key= ref->key_buff;
+ len= ref->key_length;
+ }
+
+ pos= init_pos+rec_len;
+
+ return len;
+}
+
+
+/*
+ Check the index condition of the joined table for a record from the BKA cache
+
+ SYNOPSIS
+ skip_index_tuple()
+ range_info pointer to the record returned by MRR
+
+ DESCRIPTION
+ This function is invoked from MRR implementation to check if an index
+ tuple matches the index condition. It is used in the case where the index
+ condition actually depends on both columns of the used index and columns
+ from previous tables.
+
+ NOTES
+ Accessing columns of the previous tables requires special handling with
+ BKA. The idea of BKA is to collect record combinations in a buffer and
+ then do a batch of ref access lookups, i.e. by the time we're doing a
+ lookup its previous-records-combination is not in prev_table->record[0]
+ but somewhere in the join buffer.
+ We need to get it from there back into prev_table(s)->record[0] before we
+ can evaluate the index condition, and that's why we need this function
+ instead of regular IndexConditionPushdown.
+
+ NOTES
+ Possible optimization:
+ Before we unpack the record from a previous table
+ check if this table is used in the condition.
+ If so then unpack the record otherwise skip the unpacking.
+ This should be done by a special virtual method
+ get_partial_record_by_pos().
+
+ RETURN VALUE
+ 1 the record combination does not satisfies the index condition
+ 0 otherwise
+*/
+
+bool JOIN_CACHE_BKA::skip_index_tuple(char *range_info)
+{
+ DBUG_ENTER("JOIN_CACHE_BKA::skip_index_tuple");
+ get_record_by_pos((uchar*)range_info);
+ DBUG_RETURN(!join_tab->cache_idx_cond->val_int());
+}
+
+
+
+/*
+ Initialize retrieval of range sequence for the BKAH join algorithm
+
+ SYNOPSIS
+ bkah_range_seq_init()
+ init_params pointer to the BKAH join cache object
+ n_ranges the number of ranges obtained
+ flags combination of MRR flags
+
+ DESCRIPTION
+ The function interprets init_param as a pointer to a JOIN_CACHE_BKAH
+ object. The function prepares for an iteration over distinct join keys
+ built over the records from the cache join buffer.
+
+ NOTE
+ This function are used only as a callback function.
+
+ RETURN VALUE
+ init_param value that is to be used as a parameter of
+ bkah_range_seq_next()
+*/
+
+static
+range_seq_t bkah_range_seq_init(void *init_param, uint n_ranges, uint flags)
+{
+ DBUG_ENTER("bkah_range_seq_init");
+ JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) init_param;
+ cache->reset(0);
+ DBUG_RETURN((range_seq_t) init_param);
+}
+
+
+/*
+ Get the next range/key over records from the join buffer of a BKAH cache
+
+ SYNOPSIS
+ bkah_range_seq_next()
+ seq value returned by bkah_range_seq_init()
+ range OUT reference to the next range
+
+ DESCRIPTION
+ The function interprets seq as a pointer to a JOIN_CACHE_BKAH
+ object. The function returns a pointer to the range descriptor
+ for the next unique key built over records from the join buffer.
+
+ NOTE
+ This function are used only as a callback function.
+
+ RETURN VALUE
+ FALSE ok, the range structure filled with info about the next range/key
+ TRUE no more ranges
+*/
+
+static
+bool bkah_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
+{
+ DBUG_ENTER("bkah_range_seq_next");
+ JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
+ TABLE_REF *ref= &cache->join_tab->ref;
+ key_range *start_key= &range->start_key;
+ if ((start_key->length= cache->get_next_key((uchar **) &start_key->key)))
+ {
+ start_key->keypart_map= (1 << ref->key_parts) - 1;
+ start_key->flag= HA_READ_KEY_EXACT;
+ range->end_key= *start_key;
+ range->end_key.flag= HA_READ_AFTER_KEY;
+ range->ptr= (char *) cache->get_curr_key_chain();
+ range->range_flag= EQ_RANGE;
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Check whether range_info orders to skip the next record from BKAH join buffer
+
+ SYNOPSIS
+ bkah_range_seq_skip_record()
+ seq value returned by bkah_range_seq_init()
+ range_info information about the next range/key returned by MRR
+ rowid [NOT USED] rowid of the record to be checked (not used)
+
+ DESCRIPTION
+ The function interprets seq as a pointer to a JOIN_CACHE_BKAH
+ object. The function returns TRUE if the record with this range_info
+ is to be filtered out from the stream of records returned by
+ multi_range_read_next().
+
+ NOTE
+ This function are used only as a callback function.
+
+ RETURN VALUE
+ 1 record with this range_info is to be filtered out from the stream
+ of records returned by multi_range_read_next()
+ 0 the record is to be left in the stream
+*/
+
+static
+bool bkah_range_seq_skip_record(range_seq_t rseq, char *range_info,
+ uchar *rowid)
+{
+ DBUG_ENTER("bkah_range_seq_skip_record");
+ JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
+ bool res= cache->check_all_match_flags_for_key((uchar *) range_info);
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Check if the record combination from BKAH cache matches the index condition
+
+ SYNOPSIS
+ bkah_skip_index_tuple()
+ rseq value returned by bka_range_seq_init()
+ range_info record chain for the next range/key returned by MRR
+
+ DESCRIPTION
+ This is wrapper for JOIN_CACHE_BKA_UNIQUE::skip_index_tuple method,
+ see comments there.
+
+ NOTE
+ This function is used as a RANGE_SEQ_IF::skip_index_tuple callback.
+
+ RETURN VALUE
+ 0 some records from the chain satisfy the index condition
+ 1 otherwise
+*/
+
+static
+bool bkah_skip_index_tuple(range_seq_t rseq, char *range_info)
+{
+ DBUG_ENTER("bka_unique_skip_index_tuple");
+ JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
+ DBUG_RETURN(cache->skip_index_tuple(range_info));
+}
+
+
+/*
+ Prepare to read record from BKAH cache matching the current joined record
+
+ SYNOPSIS
+ prepare_look_for_matches()
+ skip_last <-> ignore the last record in the buffer (always unused here)
+
+ DESCRIPTION
+ The function prepares to iterate over records in the join cache buffer
+ matching the record loaded into the record buffer for join_tab when
+ performing join operation by BKAH join algorithm. With BKAH algorithm, if
+ association labels are used, then record loaded into the record buffer
+ for join_tab always has a direct reference to the chain of the mathing
+ records from the join buffer. If association labels are not used then
+ then the chain of the matching records is obtained by the call of the
+ get_key_chain_by_join_key function.
+
+ RETURN VALUE
+ TRUE there are no records in the buffer to iterate over
+ FALSE otherwise
+*/
+
+bool JOIN_CACHE_BKAH::prepare_look_for_matches(bool skip_last)
+{
+ last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0;
+ if (no_association &&
+ (curr_matching_chain= get_matching_chain_by_join_key()))
+ return 1;
+ last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain);
+ return 0;
+}
+
+/*
+ Initialize the BKAH join cache
+
+ SYNOPSIS
+ init
+
+ DESCRIPTION
+ The function initializes the cache structure. It is supposed to be called
+ right after a constructor for the JOIN_CACHE_BKAH.
+
+ NOTES
+ The function first constructs a companion object of the type
+ JOIN_TAB_SCAN_MRR, then it calls the init method of the parent class.
+
+ RETURN VALUE
+ 0 initialization with buffer allocations has been succeeded
+ 1 otherwise
+*/
+
+int JOIN_CACHE_BKAH::init()
+{
+ bool check_only_first_match= join_tab->check_only_first_match();
+
+ no_association= test(mrr_mode & HA_MRR_NO_ASSOCIATION);
+
+ RANGE_SEQ_IF rs_funcs= { bka_range_seq_key_info,
+ bkah_range_seq_init,
+ bkah_range_seq_next,
+ check_only_first_match && !no_association ?
+ bkah_range_seq_skip_record : 0,
+ bkah_skip_index_tuple };
+
+ DBUG_ENTER("JOIN_CACHE_BKAH::init");
+
+ if (!(join_tab_scan= new JOIN_TAB_SCAN_MRR(join, join_tab,
+ mrr_mode, rs_funcs)))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(JOIN_CACHE_HASHED::init());
+}
+
+
+/*
+ Check the index condition of the joined table for a record from the BKA cache
+
+ SYNOPSIS
+ skip_index_tuple()
+ range_info record chain returned by MRR
+
+ DESCRIPTION
+ See JOIN_CACHE_BKA::skip_index_tuple().
+ This function is the variant for use with rhe class JOIN_CACHE_BKAH.
+ The difference from JOIN_CACHE_BKA case is that there may be multiple
+ previous table record combinations that share the same key(MRR range).
+ As a consequence, we need to loop through the chain of all table record
+ combinations that match the given MRR range key range_info until we find
+ one that satisfies the index condition.
+
+ NOTE
+ Possible optimization:
+ Before we unpack the record from a previous table
+ check if this table is used in the condition.
+ If so then unpack the record otherwise skip the unpacking.
+ This should be done by a special virtual method
+ get_partial_record_by_pos().
+
+ RETURN VALUE
+ 1 any record combination from the chain referred by range_info
+ does not satisfy the index condition
+ 0 otherwise
+
+
+*/
+
+bool JOIN_CACHE_BKAH::skip_index_tuple(char *range_info)
+{
+ uchar *last_rec_ref_ptr= get_next_rec_ref((uchar*) range_info);
+ uchar *next_rec_ref_ptr= last_rec_ref_ptr;
+ DBUG_ENTER("JOIN_CACHE_BKAH::skip_index_tuple");
+ do
+ {
+ next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
+ uchar *rec_ptr= next_rec_ref_ptr + rec_fields_offset;
+ get_record_by_pos(rec_ptr);
+ if (join_tab->cache_idx_cond->val_int())
+ DBUG_RETURN(FALSE);
+ } while(next_rec_ref_ptr != last_rec_ref_ptr);
+ DBUG_RETURN(TRUE);
+}
diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h
new file mode 100644
index 00000000000..546067fad24
--- /dev/null
+++ b/sql/sql_join_cache.h
@@ -0,0 +1,1407 @@
+/*
+ This file contains declarations for implementations
+ of block based join algorithms
+*/
+
+#define JOIN_CACHE_INCREMENTAL_BIT 1
+#define JOIN_CACHE_HASHED_BIT 2
+#define JOIN_CACHE_BKA_BIT 4
+
+/*
+ Categories of data fields of variable length written into join cache buffers.
+ The value of any of these fields is written into cache together with the
+ prepended length of the value.
+*/
+#define CACHE_BLOB 1 /* blob field */
+#define CACHE_STRIPPED 2 /* field stripped of trailing spaces */
+#define CACHE_VARSTR1 3 /* short string value (length takes 1 byte) */
+#define CACHE_VARSTR2 4 /* long string value (length takes 2 bytes) */
+
+/*
+ The CACHE_FIELD structure used to describe fields of records that
+ are written into a join cache buffer from record buffers and backward.
+*/
+typedef struct st_cache_field {
+ uchar *str; /**< buffer from/to where the field is to be copied */
+ uint length; /**< maximal number of bytes to be copied from/to str */
+ /*
+ Field object for the moved field
+ (0 - for a flag field, see JOIN_CACHE::create_flag_fields).
+ */
+ Field *field;
+ uint type; /**< category of the of the copied field (CACHE_BLOB et al.) */
+ /*
+ The number of the record offset value for the field in the sequence
+ of offsets placed after the last field of the record. These
+ offset values are used to access fields referred to from other caches.
+ If the value is 0 then no offset for the field is saved in the
+ trailing sequence of offsets.
+ */
+ uint referenced_field_no;
+ /* The remaining structure fields are used as containers for temp values */
+ uint blob_length; /**< length of the blob to be copied */
+ uint offset; /**< field offset to be saved in cache buffer */
+} CACHE_FIELD;
+
+
+class JOIN_TAB_SCAN;
+
+
+/*
+ JOIN_CACHE is the base class to support the implementations of
+ - Block Nested Loop (BNL) Join Algorithm,
+ - Block Nested Loop Hash (BNLH) Join Algorithm,
+ - Batched Key Access (BKA) Join Algorithm.
+ The first algorithm is supported by the derived class JOIN_CACHE_BNL,
+ the second algorithm is supported by the derived class JOIN_CACHE_BNLH,
+ while the third algorithm is implemented in two variant supported by
+ the classes JOIN_CACHE_BKA and JOIN_CACHE_BKAH.
+ These three algorithms have a lot in common. Each of them first accumulates
+ the records of the left join operand in a join buffer and then searches for
+ matching rows of the second operand for all accumulated records.
+ For the first two algorithms this strategy saves on logical I/O operations:
+ the entire set of records from the join buffer requires only one look-through
+ of the records provided by the second operand.
+ For the third algorithm the accumulation of records allows to optimize
+ fetching rows of the second operand from disk for some engines (MyISAM,
+ InnoDB), or to minimize the number of round-trips between the Server and
+ the engine nodes (NDB Cluster).
+*/
+
+class JOIN_CACHE :public Sql_alloc
+{
+
+private:
+
+ /* Size of the offset of a record from the cache */
+ uint size_of_rec_ofs;
+ /* Size of the length of a record in the cache */
+ uint size_of_rec_len;
+ /* Size of the offset of a field within a record in the cache */
+ uint size_of_fld_ofs;
+
+protected:
+
+ /* 3 functions below actually do not use the hidden parameter 'this' */
+
+ /* Calculate the number of bytes used to store an offset value */
+ uint offset_size(uint len)
+ { return (len < 256 ? 1 : len < 256*256 ? 2 : 4); }
+
+ /* Get the offset value that takes ofs_sz bytes at the position ptr */
+ ulong get_offset(uint ofs_sz, uchar *ptr)
+ {
+ switch (ofs_sz) {
+ case 1: return uint(*ptr);
+ case 2: return uint2korr(ptr);
+ case 4: return uint4korr(ptr);
+ }
+ return 0;
+ }
+
+ /* Set the offset value ofs that takes ofs_sz bytes at the position ptr */
+ void store_offset(uint ofs_sz, uchar *ptr, ulong ofs)
+ {
+ switch (ofs_sz) {
+ case 1: *ptr= (uchar) ofs; return;
+ case 2: int2store(ptr, (uint16) ofs); return;
+ case 4: int4store(ptr, (uint32) ofs); return;
+ }
+ }
+
+ /*
+ The maximum total length of the fields stored for a record in the cache.
+ For blob fields only the sizes of the blob lengths are taken into account.
+ */
+ uint length;
+
+ /*
+ Representation of the executed multi-way join through which all needed
+ context can be accessed.
+ */
+ JOIN *join;
+
+ /*
+ Cardinality of the range of join tables whose fields can be put into the
+ cache. A table from the range not necessarily contributes to the cache.
+ */
+ uint tables;
+
+ /*
+ The total number of flag and data fields that can appear in a record
+ written into the cache. Fields with null values are always skipped
+ to save space.
+ */
+ uint fields;
+
+ /*
+ The total number of flag fields in a record put into the cache. They are
+ used for table null bitmaps, table null row flags, and an optional match
+ flag. Flag fields go before other fields in a cache record with the match
+ flag field placed always at the very beginning of the record.
+ */
+ uint flag_fields;
+
+ /* The total number of blob fields that are written into the cache */
+ uint blobs;
+
+ /*
+ The total number of fields referenced from field descriptors for other join
+ caches. These fields are used to construct key values.
+ When BKA join algorithm is employed the constructed key values serve to
+ access matching rows with index lookups.
+ The key values are put into a hash table when the BNLH join algorithm
+ is employed and when BKAH is used for the join operation.
+ */
+ uint referenced_fields;
+
+ /*
+ The current number of already created data field descriptors.
+ This number can be useful for implementations of the init methods.
+ */
+ uint data_field_count;
+
+ /*
+ The current number of already created pointers to the data field
+ descriptors. This number can be useful for implementations of
+ the init methods.
+ */
+ uint data_field_ptr_count;
+
+ /*
+ Array of the descriptors of fields containing 'fields' elements.
+ These are all fields that are stored for a record in the cache.
+ */
+ CACHE_FIELD *field_descr;
+
+ /*
+ Array of pointers to the blob descriptors that contains 'blobs' elements.
+ */
+ CACHE_FIELD **blob_ptr;
+
+ /*
+ This flag indicates that records written into the join buffer contain
+ a match flag field. The flag must be set by the init method.
+ */
+ bool with_match_flag;
+ /*
+ This flag indicates that any record is prepended with the length of the
+ record which allows us to skip the record or part of it without reading.
+ */
+ bool with_length;
+
+ /*
+ The maximal number of bytes used for a record representation in
+ the cache excluding the space for blob data.
+ For future derived classes this representation may contains some
+ redundant info such as a key value associated with the record.
+ */
+ uint pack_length;
+ /*
+ The value of pack_length incremented by the total size of all
+ pointers of a record in the cache to the blob data.
+ */
+ uint pack_length_with_blob_ptrs;
+
+ /*
+ The total size of the record base prefix. The base prefix of record may
+ include the following components:
+ - the length of the record
+ - the link to a record in a previous buffer.
+ Each record in the buffer are supplied with the same set of the components.
+ */
+ uint base_prefix_length;
+
+ /*
+ The expected length of a record in the join buffer together with
+ all prefixes and postfixes
+ */
+ ulong avg_record_length;
+
+ /* The expected size of the space per record in the auxiliary buffer */
+ ulong avg_aux_buffer_incr;
+
+ /* Expected join buffer space used for one record */
+ ulong space_per_record;
+
+ /* Pointer to the beginning of the join buffer */
+ uchar *buff;
+ /*
+ Size of the entire memory allocated for the join buffer.
+ Part of this memory may be reserved for the auxiliary buffer.
+ */
+ ulong buff_size;
+ /* The minimal join buffer size when join buffer still makes sense to use */
+ ulong min_buff_size;
+ /* The maximum expected size if the join buffer to be used */
+ ulong max_buff_size;
+ /* Size of the auxiliary buffer */
+ ulong aux_buff_size;
+
+ /* The number of records put into the join buffer */
+ ulong records;
+ /*
+ The number of records in the fully refilled join buffer of
+ the minimal size equal to min_buff_size
+ */
+ ulong min_records;
+ /*
+ The maximum expected number of records to be put in the join buffer
+ at one refill
+ */
+ ulong max_records;
+
+ /*
+ Pointer to the current position in the join buffer.
+ This member is used both when writing to buffer and
+ when reading from it.
+ */
+ uchar *pos;
+ /*
+ Pointer to the first free position in the join buffer,
+ right after the last record into it.
+ */
+ uchar *end_pos;
+
+ /*
+ Pointer to the beginning of the first field of the current read/write
+ record from the join buffer. The value is adjusted by the
+ get_record/put_record functions.
+ */
+ uchar *curr_rec_pos;
+ /*
+ Pointer to the beginning of the first field of the last record
+ from the join buffer.
+ */
+ uchar *last_rec_pos;
+
+ /*
+ Flag is set if the blob data for the last record in the join buffer
+ is in record buffers rather than in the join cache.
+ */
+ bool last_rec_blob_data_is_in_rec_buff;
+
+ /*
+ Pointer to the position to the current record link.
+ Record links are used only with linked caches. Record links allow to set
+ connections between parts of one join record that are stored in different
+ join buffers.
+ In the simplest case a record link is just a pointer to the beginning of
+ the record stored in the buffer.
+ In a more general case a link could be a reference to an array of pointers
+ to records in the buffer.
+ */
+ uchar *curr_rec_link;
+
+ /*
+ This flag is set to TRUE if join_tab is the first inner table of an outer
+ join and the latest record written to the join buffer is detected to be
+ null complemented after checking on conditions over the outer tables for
+ this outer join operation
+ */
+ bool last_written_is_null_compl;
+
+ /*
+ The number of fields put in the join buffer of the join cache that are
+ used in building keys to access the table join_tab
+ */
+ uint local_key_arg_fields;
+ /*
+ The total number of the fields in the previous caches that are used
+ in building keys to access the table join_tab
+ */
+ uint external_key_arg_fields;
+
+ /*
+ This flag indicates that the key values will be read directly from the join
+ buffer. It will save us building key values in the key buffer.
+ */
+ bool use_emb_key;
+ /* The length of an embedded key value */
+ uint emb_key_length;
+
+ /*
+ This object provides the methods to iterate over records of
+ the joined table join_tab when looking for join matches between
+ records from join buffer and records from join_tab.
+ BNL and BNLH join algorithms retrieve all records from join_tab,
+ while BKA/BKAH algorithm iterates only over those records from
+ join_tab that can be accessed by look-ups with join keys built
+ from records in join buffer.
+ */
+ JOIN_TAB_SCAN *join_tab_scan;
+
+ void calc_record_fields();
+ void collect_info_on_key_args();
+ int alloc_fields();
+ void create_flag_fields();
+ void create_key_arg_fields();
+ void create_remaining_fields();
+ void set_constants();
+ int alloc_buffer();
+
+ /* Shall reallocate the join buffer */
+ virtual int realloc_buffer();
+
+ /* Check the possibility to read the access keys directly from join buffer */
+ bool check_emb_key_usage();
+
+ uint get_size_of_rec_offset() { return size_of_rec_ofs; }
+ uint get_size_of_rec_length() { return size_of_rec_len; }
+ uint get_size_of_fld_offset() { return size_of_fld_ofs; }
+
+ uchar *get_rec_ref(uchar *ptr)
+ {
+ return buff+get_offset(size_of_rec_ofs, ptr-size_of_rec_ofs);
+ }
+ ulong get_rec_length(uchar *ptr)
+ {
+ return (ulong) get_offset(size_of_rec_len, ptr);
+ }
+ ulong get_fld_offset(uchar *ptr)
+ {
+ return (ulong) get_offset(size_of_fld_ofs, ptr);
+ }
+
+ void store_rec_ref(uchar *ptr, uchar* ref)
+ {
+ store_offset(size_of_rec_ofs, ptr-size_of_rec_ofs, (ulong) (ref-buff));
+ }
+ void store_rec_length(uchar *ptr, ulong len)
+ {
+ store_offset(size_of_rec_len, ptr, len);
+ }
+ void store_fld_offset(uchar *ptr, ulong ofs)
+ {
+ store_offset(size_of_fld_ofs, ptr, ofs);
+ }
+
+ /* Write record fields and their required offsets into the join buffer */
+ uint write_record_data(uchar *link, bool *is_full);
+
+ /* Get the total length of all prefixes of a record in the join buffer */
+ virtual uint get_prefix_length() { return base_prefix_length; }
+ /* Get maximum total length of all affixes of a record in the join buffer */
+ virtual uint get_record_max_affix_length();
+
+ /*
+ Shall get maximum size of the additional space per record used for
+ record keys
+ */
+ virtual uint get_max_key_addon_space_per_record() { return 0; }
+
+ /*
+ This method must determine for how much the auxiliary buffer should be
+ incremented when a new record is added to the join buffer.
+ If no auxiliary buffer is needed the function should return 0.
+ */
+ virtual uint aux_buffer_incr(ulong recno);
+
+ /* Shall calculate how much space is remaining in the join buffer */
+ virtual ulong rem_space()
+ {
+ return max(buff_size-(end_pos-buff)-aux_buff_size,0);
+ }
+
+ /*
+ Shall calculate how much space is taken by allocation of the key
+ for a record in the join buffer
+ */
+ virtual uint extra_key_length() { return 0; }
+
+ /* Read all flag and data fields of a record from the join buffer */
+ uint read_all_record_fields();
+
+ /* Read all flag fields of a record from the join buffer */
+ uint read_flag_fields();
+
+ /* Read a data record field from the join buffer */
+ uint read_record_field(CACHE_FIELD *copy, bool last_record);
+
+ /* Read a referenced field from the join buffer */
+ bool read_referenced_field(CACHE_FIELD *copy, uchar *rec_ptr, uint *len);
+
+ /*
+ Shall skip record from the join buffer if its match flag
+ is set to MATCH_FOUND
+ */
+ virtual bool skip_if_matched();
+
+ /*
+ Shall skip record from the join buffer if its match flag
+ commands to do so
+ */
+ virtual bool skip_if_not_needed_match();
+
+ /*
+ True if rec_ptr points to the record whose blob data stay in
+ record buffers
+ */
+ bool blob_data_is_in_rec_buff(uchar *rec_ptr)
+ {
+ return rec_ptr == last_rec_pos && last_rec_blob_data_is_in_rec_buff;
+ }
+
+ /* Find matches from the next table for records from the join buffer */
+ virtual enum_nested_loop_state join_matching_records(bool skip_last);
+
+ /* Shall set an auxiliary buffer up (currently used only by BKA joins) */
+ virtual int setup_aux_buffer(HANDLER_BUFFER &aux_buff)
+ {
+ DBUG_ASSERT(0);
+ return 0;
+ }
+
+ /*
+ Shall get the number of ranges in the cache buffer passed
+ to the MRR interface
+ */
+ virtual uint get_number_of_ranges_for_mrr() { return 0; };
+
+ /*
+ Shall prepare to look for records from the join cache buffer that would
+ match the record of the joined table read into the record buffer
+ */
+ virtual bool prepare_look_for_matches(bool skip_last)= 0;
+ /*
+ Shall return a pointer to the record from join buffer that is checked
+ as the next candidate for a match with the current record from join_tab.
+ Each implementation of this virtual function should bare in mind
+ that the record position it returns shall be exactly the position
+ passed as the parameter to the implementations of the virtual functions
+ skip_next_candidate_for_match and read_next_candidate_for_match.
+ */
+ virtual uchar *get_next_candidate_for_match()= 0;
+ /*
+ Shall check whether the given record from the join buffer has its match
+ flag settings commands to skip the record in the buffer.
+ */
+ virtual bool skip_next_candidate_for_match(uchar *rec_ptr)= 0;
+ /*
+ Shall read the given record from the join buffer into the
+ the corresponding record buffer
+ */
+ virtual void read_next_candidate_for_match(uchar *rec_ptr)= 0;
+
+ /*
+ Shall return the location of the association label returned by
+ the multi_read_range_next function for the current record loaded
+ into join_tab's record buffer
+ */
+ virtual uchar **get_curr_association_ptr() { return 0; };
+
+ /* Add null complements for unmatched outer records from the join buffer */
+ virtual enum_nested_loop_state join_null_complements(bool skip_last);
+
+ /* Restore the fields of the last record from the join buffer */
+ virtual void restore_last_record();
+
+ /* Set match flag for a record in join buffer if it has not been set yet */
+ bool set_match_flag_if_none(JOIN_TAB *first_inner, uchar *rec_ptr);
+
+ enum_nested_loop_state generate_full_extensions(uchar *rec_ptr);
+
+ /* Check matching to a partial join record from the join buffer */
+ bool check_match(uchar *rec_ptr);
+
+ /*
+ This constructor creates an unlinked join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter.
+ */
+ JOIN_CACHE(JOIN *j, JOIN_TAB *tab)
+ {
+ join= j;
+ join_tab= tab;
+ prev_cache= next_cache= 0;
+ buff= 0;
+ }
+
+ /*
+ This constructor creates a linked join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter. The parameter 'prev' specifies the previous
+ cache object to which this cache is linked.
+ */
+ JOIN_CACHE(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
+ {
+ join= j;
+ join_tab= tab;
+ next_cache= 0;
+ prev_cache= prev;
+ buff= 0;
+ if (prev)
+ prev->next_cache= this;
+ }
+
+public:
+
+ /*
+ The enumeration type Join_algorithm includes a mnemonic constant for
+ each join algorithm that employs join buffers
+ */
+
+ enum Join_algorithm
+ {
+ BNL_JOIN_ALG, /* Block Nested Loop Join algorithm */
+ BNLH_JOIN_ALG, /* Block Nested Loop Hash Join algorithm */
+ BKA_JOIN_ALG, /* Batched Key Access Join algorithm */
+ BKAH_JOIN_ALG, /* Batched Key Access with Hash Table Join Algorithm */
+ };
+
+ /*
+ The enumeration type Match_flag describes possible states of the match flag
+ field stored for the records of the first inner tables of outer joins and
+ semi-joins in the cases when the first match strategy is used for them.
+ When a record with match flag field is written into the join buffer the
+ state of the field usually is MATCH_NOT_FOUND unless this is a record of the
+ first inner table of the outer join for which the on precondition (the
+ condition from on expression over outer tables) has turned out not to be
+ true. In the last case the state of the match flag is MATCH_IMPOSSIBLE.
+ The state of the match flag field is changed to MATCH_FOUND as soon as
+ the first full matching combination of inner tables of the outer join or
+ the semi-join is discovered.
+ */
+ enum Match_flag { MATCH_NOT_FOUND, MATCH_FOUND, MATCH_IMPOSSIBLE };
+
+ /* Table to be joined with the partial join records from the cache */
+ JOIN_TAB *join_tab;
+
+ /* Pointer to the previous join cache if there is any */
+ JOIN_CACHE *prev_cache;
+ /* Pointer to the next join cache if there is any */
+ JOIN_CACHE *next_cache;
+
+ /* Shall initialize the join cache structure */
+ virtual int init();
+
+ /* Get the current size of the cache join buffer */
+ ulong get_join_buffer_size() { return buff_size; }
+ /* Set the size of the cache join buffer to a new value */
+ void set_join_buffer_size(ulong sz) { buff_size= sz; }
+
+ /* Get the minimum possible size of the cache join buffer */
+ virtual ulong get_min_join_buffer_size();
+ /* Get the maximum possible size of the cache join buffer */
+ virtual ulong get_max_join_buffer_size();
+
+ /* Shrink the size if the cache join buffer in a given ratio */
+ bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);
+
+ /* Shall return the type of the employed join algorithm */
+ virtual enum Join_algorithm get_join_alg()= 0;
+
+ /*
+ The function shall return TRUE only when there is a key access
+ to the join table
+ */
+ virtual bool is_key_access()= 0;
+
+ /* Shall reset the join buffer for reading/writing */
+ virtual void reset(bool for_writing);
+
+ /*
+ This function shall add a record into the join buffer and return TRUE
+ if it has been decided that it should be the last record in the buffer.
+ */
+ virtual bool put_record();
+
+ /*
+ This function shall read the next record into the join buffer and return
+ TRUE if there is no more next records.
+ */
+ virtual bool get_record();
+
+ /*
+ This function shall read the record at the position rec_ptr
+ in the join buffer
+ */
+ virtual void get_record_by_pos(uchar *rec_ptr);
+
+ /* Shall return the value of the match flag for the positioned record */
+ virtual enum Match_flag get_match_flag_by_pos(uchar *rec_ptr);
+
+ /* Shall return the position of the current record */
+ virtual uchar *get_curr_rec() { return curr_rec_pos; }
+
+ /* Shall set the current record link */
+ virtual void set_curr_rec_link(uchar *link) { curr_rec_link= link; }
+
+ /* Shall return the current record link */
+ virtual uchar *get_curr_rec_link()
+ {
+ return (curr_rec_link ? curr_rec_link : get_curr_rec());
+ }
+
+ /* Join records from the join buffer with records from the next join table */
+ enum_nested_loop_state join_records(bool skip_last);
+
+ /* Add a comment on the join algorithm employed by the join cache */
+ void print_explain_comment(String *str);
+
+ virtual ~JOIN_CACHE() {}
+ void reset_join(JOIN *j) { join= j; }
+ void free()
+ {
+ x_free(buff);
+ buff= 0;
+ }
+
+ JOIN_TAB *get_next_table(JOIN_TAB *tab);
+
+ friend class JOIN_CACHE_HASHED;
+ friend class JOIN_CACHE_BNL;
+ friend class JOIN_CACHE_BKA;
+ friend class JOIN_TAB_SCAN;
+ friend class JOIN_TAB_SCAN_MRR;
+
+};
+
+
+/*
+ The class JOIN_CACHE_HASHED is the base class for the classes
+ JOIN_CACHE_HASHED_BNL and JOIN_CACHE_HASHED_BKA. The first of them supports
+ an implementation of Block Nested Loop Hash (BNLH) Join Algorithm,
+ while the second is used for a variant of the BKA Join algorithm that performs
+ only one lookup for any records from join buffer with the same key value.
+ For a join cache of this class the records from the join buffer that have
+ the same access key are linked into a chain attached to a key entry structure
+ that either itself contains the key value, or, in the case when the keys are
+ embedded, refers to its occurrence in one of the records from the chain.
+ To build the chains with the same keys a hash table is employed. It is placed
+ at the very end of the join buffer. The array of hash entries is allocated
+ first at the very bottom of the join buffer, while key entries are placed
+ before this array.
+ A hash entry contains a header of the list of the key entries with the same
+ hash value.
+ Each key entry is a structure of the following type:
+ struct st_join_cache_key_entry {
+ union {
+ uchar[] value;
+ cache_ref *value_ref; // offset from the beginning of the buffer
+ } hash_table_key;
+ key_ref next_key; // offset backward from the beginning of hash table
+ cache_ref *last_rec // offset from the beginning of the buffer
+ }
+ The references linking the records in a chain are always placed at the very
+ beginning of the record info stored in the join buffer. The records are
+ linked in a circular list. A new record is always added to the end of this
+ list.
+
+ The following picture represents a typical layout for the info stored in the
+ join buffer of a join cache object of the JOIN_CACHE_HASHED class.
+
+ buff
+ V
+ +----------------------------------------------------------------------------+
+ | |[*]record_1_1| |
+ | ^ | |
+ | | +--------------------------------------------------+ |
+ | | |[*]record_2_1| | |
+ | | ^ | V |
+ | | | +------------------+ |[*]record_1_2| |
+ | | +--------------------+-+ | |
+ |+--+ +---------------------+ | | +-------------+ |
+ || | | V | | |
+ |||[*]record_3_1| |[*]record_1_3| |[*]record_2_2| | |
+ ||^ ^ ^ | |
+ ||+----------+ | | | |
+ ||^ | |<---------------------------+-------------------+ |
+ |++ | | ... mrr | buffer ... ... | | |
+ | | | | |
+ | +-----+--------+ | +-----|-------+ |
+ | V | | | V | | |
+ ||key_3|[/]|[*]| | | |key_2|[/]|[*]| | |
+ | +-+---|-----------------------+ | |
+ | V | | | | |
+ | |key_1|[*]|[*]| | | ... |[*]| ... |[*]| ... | |
+ +----------------------------------------------------------------------------+
+ ^ ^ ^
+ | i-th entry j-th entry
+ hash table
+
+ i-th hash entry:
+ circular record chain for key_1:
+ record_1_1
+ record_1_2
+ record_1_3 (points to record_1_1)
+ circular record chain for key_3:
+ record_3_1 (points to itself)
+
+ j-th hash entry:
+ circular record chain for key_2:
+ record_2_1
+ record_2_2 (points to record_2_1)
+
+*/
+
+class JOIN_CACHE_HASHED: public JOIN_CACHE
+{
+
+ typedef uint (JOIN_CACHE_HASHED::*Hash_func) (uchar *key, uint key_len);
+ typedef bool (JOIN_CACHE_HASHED::*Hash_cmp_func) (uchar *key1, uchar *key2,
+ uint key_len);
+
+private:
+
+ /* Size of the offset of a key entry in the hash table */
+ uint size_of_key_ofs;
+
+ /*
+ Length of the key entry in the hash table.
+ A key entry either contains the key value, or it contains a reference
+ to the key value if use_emb_key flag is set for the cache.
+ */
+ uint key_entry_length;
+
+ /* The beginning of the hash table in the join buffer */
+ uchar *hash_table;
+ /* Number of hash entries in the hash table */
+ uint hash_entries;
+
+
+ /* The position of the currently retrieved key entry in the hash table */
+ uchar *curr_key_entry;
+
+ /* The offset of the data fields from the beginning of the record fields */
+ uint data_fields_offset;
+
+ inline uint get_hash_idx_simple(uchar *key, uint key_len);
+ inline uint get_hash_idx_complex(uchar *key, uint key_len);
+
+ inline bool equal_keys_simple(uchar *key1, uchar *key2, uint key_len);
+ inline bool equal_keys_complex(uchar *key1, uchar *key2, uint key_len);
+
+ int init_hash_table();
+ void cleanup_hash_table();
+
+protected:
+
+ /*
+ Index info on the TABLE_REF object used by the hash join
+ to look for matching records
+ */
+ KEY *ref_key_info;
+ /*
+ Number of the key parts the TABLE_REF object used by the hash join
+ to look for matching records
+ */
+ uint ref_used_key_parts;
+
+ /*
+ The hash function used in the hash table,
+ usually set by the init() method
+ */
+ Hash_func hash_func;
+ /*
+ The function to check whether two key entries in the hash table
+ are equal or not, usually set by the init() method
+ */
+ Hash_cmp_func hash_cmp_func;
+
+ /*
+ Length of a key value.
+ It is assumed that all key values have the same length.
+ */
+ uint key_length;
+ /* Buffer to store key values for probing */
+ uchar *key_buff;
+
+ /* Number of key entries in the hash table (number of distinct keys) */
+ uint key_entries;
+
+ /* The position of the last key entry in the hash table */
+ uchar *last_key_entry;
+
+ /*
+ The offset of the record fields from the beginning of the record
+ representation. The record representation starts with a reference to
+ the next record in the key record chain followed by the length of
+ the trailing record data followed by a reference to the record segment
+ in the previous cache, if any, followed by the record fields.
+ */
+ uint rec_fields_offset;
+
+ uint get_size_of_key_offset() { return size_of_key_ofs; }
+
+ /*
+ Get the position of the next_key_ptr field pointed to by
+ a linking reference stored at the position key_ref_ptr.
+ This reference is actually the offset backward from the
+ beginning of hash table.
+ */
+ uchar *get_next_key_ref(uchar *key_ref_ptr)
+ {
+ return hash_table-get_offset(size_of_key_ofs, key_ref_ptr);
+ }
+
+ /*
+ Store the linking reference to the next_key_ptr field at
+ the position key_ref_ptr. The position of the next_key_ptr
+ field is pointed to by ref. The stored reference is actually
+ the offset backward from the beginning of the hash table.
+ */
+ void store_next_key_ref(uchar *key_ref_ptr, uchar *ref)
+ {
+ store_offset(size_of_key_ofs, key_ref_ptr, (ulong) (hash_table-ref));
+ }
+
+ /*
+ Check whether the reference to the next_key_ptr field at the position
+ key_ref_ptr contains a nil value.
+ */
+ bool is_null_key_ref(uchar *key_ref_ptr)
+ {
+ ulong nil= 0;
+ return memcmp(key_ref_ptr, &nil, size_of_key_ofs ) == 0;
+ }
+
+ /*
+ Set the reference to the next_key_ptr field at the position
+ key_ref_ptr equal to nil.
+ */
+ void store_null_key_ref(uchar *key_ref_ptr)
+ {
+ ulong nil= 0;
+ store_offset(size_of_key_ofs, key_ref_ptr, nil);
+ }
+
+ uchar *get_next_rec_ref(uchar *ref_ptr)
+ {
+ return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
+ }
+
+ void store_next_rec_ref(uchar *ref_ptr, uchar *ref)
+ {
+ store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
+ }
+
+ /*
+ Get the position of the embedded key value for the current
+ record pointed to by get_curr_rec().
+ */
+ uchar *get_curr_emb_key()
+ {
+ return get_curr_rec()+data_fields_offset;
+ }
+
+ /*
+ Get the position of the embedded key value pointed to by a reference
+ stored at ref_ptr. The stored reference is actually the offset from
+ the beginning of the join buffer.
+ */
+ uchar *get_emb_key(uchar *ref_ptr)
+ {
+ return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
+ }
+
+ /*
+ Store the reference to an embedded key at the position key_ref_ptr.
+ The position of the embedded key is pointed to by ref. The stored
+ reference is actually the offset from the beginning of the join buffer.
+ */
+ void store_emb_key_ref(uchar *ref_ptr, uchar *ref)
+ {
+ store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
+ }
+
+ /* Get the total length of all prefixes of a record in hashed join buffer */
+ uint get_prefix_length()
+ {
+ return base_prefix_length + get_size_of_rec_offset();
+ }
+
+ /*
+ Get maximum size of the additional space per record used for
+ the hash table with record keys
+ */
+ uint get_max_key_addon_space_per_record();
+
+ /*
+ Calculate how much space in the buffer would not be occupied by
+ records, key entries and additional memory for the MMR buffer.
+ */
+ ulong rem_space()
+ {
+ return max(last_key_entry-end_pos-aux_buff_size,0);
+ }
+
+ /*
+ Calculate how much space is taken by allocation of the key
+ entry for a record in the join buffer
+ */
+ uint extra_key_length() { return key_entry_length; }
+
+ /*
+ Skip record from a hashed join buffer if its match flag
+ is set to MATCH_FOUND
+ */
+ bool skip_if_matched();
+
+ /*
+ Skip record from a hashed join buffer if its match flag setting
+ commands to do so
+ */
+ bool skip_if_not_needed_match();
+
+ /* Search for a key in the hash table of the join buffer */
+ bool key_search(uchar *key, uint key_len, uchar **key_ref_ptr);
+
+ /* Reallocate the join buffer of a hashed join cache */
+ int realloc_buffer();
+
+ /*
+ This constructor creates an unlinked hashed join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter.
+ */
+ JOIN_CACHE_HASHED(JOIN *j, JOIN_TAB *tab) :JOIN_CACHE(j, tab) {}
+
+ /*
+ This constructor creates a linked hashed join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter. The parameter 'prev' specifies the previous
+ cache object to which this cache is linked.
+ */
+ JOIN_CACHE_HASHED(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
+ :JOIN_CACHE(j, tab, prev) {}
+
+public:
+
+ /* Initialize a hashed join cache */
+ int init();
+
+ /* Reset the buffer of a hashed join cache for reading/writing */
+ void reset(bool for_writing);
+
+ /* Add a record into the buffer of a hashed join cache */
+ bool put_record();
+
+ /* Read the next record from the buffer of a hashed join cache */
+ bool get_record();
+
+ /*
+ Shall check whether all records in a key chain have
+ their match flags set on
+ */
+ virtual bool check_all_match_flags_for_key(uchar *key_chain_ptr);
+
+ uint get_next_key(uchar **key);
+
+ /* Get the head of the record chain attached to the current key entry */
+ uchar *get_curr_key_chain()
+ {
+ return get_next_rec_ref(curr_key_entry+key_entry_length-
+ get_size_of_rec_offset());
+ }
+
+};
+
+
+/*
+ The class JOIN_TAB_SCAN is a companion class for the classes JOIN_CACHE_BNL
+ and JOIN_CACHE_BNLH. Actually the class implements the iterator over the
+ table joinded by BNL/BNLH join algorithm.
+ The virtual functions open, next and close are called for any iteration over
+ the table. The function open is called to initiate the process of the
+ iteration. The function next shall read the next record from the joined
+ table. The record is read into the record buffer of the joined table.
+ The record is to be matched with records from the join cache buffer.
+ The function close shall perform the finalizing actions for the iteration.
+*/
+
+class JOIN_TAB_SCAN: public Sql_alloc
+{
+
+private:
+ /* TRUE if this is the first record from the joined table to iterate over */
+ bool is_first_record;
+
+protected:
+
+ /* The joined table to be iterated over */
+ JOIN_TAB *join_tab;
+ /* The join cache used to join the table join_tab */
+ JOIN_CACHE *cache;
+ /*
+ Representation of the executed multi-way join through which
+ all needed context can be accessed.
+ */
+ JOIN *join;
+
+public:
+
+ JOIN_TAB_SCAN(JOIN *j, JOIN_TAB *tab)
+ {
+ join= j;
+ join_tab= tab;
+ cache= join_tab->cache;
+ }
+
+ virtual ~JOIN_TAB_SCAN() {}
+
+ /*
+ Shall calculate the increment of the auxiliary buffer for a record
+ write if such a buffer is used by the table scan object
+ */
+ virtual uint aux_buffer_incr(ulong recno) { return 0; }
+
+ /* Initiate the process of iteration over the joined table */
+ virtual int open();
+ /*
+ Shall read the next candidate for matches with records from
+ the join buffer.
+ */
+ virtual int next();
+ /*
+ Perform the finalizing actions for the process of iteration
+ over the joined_table.
+ */
+ virtual void close();
+
+};
+
+/*
+ The class JOIN_CACHE_BNL is used when the BNL join algorithm is
+ employed to perform a join operation
+*/
+
+class JOIN_CACHE_BNL :public JOIN_CACHE
+{
+private:
+ /*
+ The number of the records in the join buffer that have to be
+ checked yet for a match with the current record of join_tab
+ read into the record buffer.
+ */
+ uint rem_records;
+
+protected:
+
+ bool prepare_look_for_matches(bool skip_last);
+
+ uchar *get_next_candidate_for_match();
+
+ bool skip_next_candidate_for_match(uchar *rec_ptr);
+
+ void read_next_candidate_for_match(uchar *rec_ptr);
+
+public:
+
+ /*
+ This constructor creates an unlinked BNL join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter.
+ */
+ JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab) :JOIN_CACHE(j, tab) {}
+
+ /*
+ This constructor creates a linked BNL join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter. The parameter 'prev' specifies the previous
+ cache object to which this cache is linked.
+ */
+ JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
+ :JOIN_CACHE(j, tab, prev) {}
+
+ /* Initialize the BNL cache */
+ int init();
+
+ enum Join_algorithm get_join_alg() { return BNL_JOIN_ALG; }
+
+ bool is_key_access() { return FALSE; }
+
+};
+
+
+/*
+ The class JOIN_CACHE_BNLH is used when the BNLH join algorithm is
+ employed to perform a join operation
+*/
+
+class JOIN_CACHE_BNLH :public JOIN_CACHE_HASHED
+{
+
+protected:
+
+ /*
+ The pointer to the last record from the circular list of the records
+ that match the join key built out of the record in the join buffer for
+ the join_tab table
+ */
+ uchar *last_matching_rec_ref_ptr;
+ /*
+ The pointer to the next current record from the circular list of the
+ records that match the join key built out of the record in the join buffer
+ for the join_tab table. This pointer is used by the class method
+ get_next_candidate_for_match to iterate over records from the circular
+ list.
+ */
+ uchar *next_matching_rec_ref_ptr;
+
+ /*
+ Get the chain of records from buffer matching the current candidate
+ record for join
+ */
+ uchar *get_matching_chain_by_join_key();
+
+ bool prepare_look_for_matches(bool skip_last);
+
+ uchar *get_next_candidate_for_match();
+
+ bool skip_next_candidate_for_match(uchar *rec_ptr);
+
+ void read_next_candidate_for_match(uchar *rec_ptr);
+
+public:
+
+ /*
+ This constructor creates an unlinked BNLH join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter.
+ */
+ JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab) : JOIN_CACHE_HASHED(j, tab) {}
+
+ /*
+ This constructor creates a linked BNLH join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter. The parameter 'prev' specifies the previous
+ cache object to which this cache is linked.
+ */
+ JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
+ : JOIN_CACHE_HASHED(j, tab, prev) {}
+
+ /* Initialize the BNLH cache */
+ int init();
+
+ enum Join_algorithm get_join_alg() { return BNLH_JOIN_ALG; }
+
+ bool is_key_access() { return TRUE; }
+
+};
+
+
+/*
+ The class JOIN_TAB_SCAN_MRR is a companion class for the classes
+ JOIN_CACHE_BKA and JOIN_CACHE_BKAH. Actually the class implements the
+ iterator over the records from join_tab selected by BKA/BKAH join
+ algorithm as the candidates to be joined.
+ The virtual functions open, next and close are called for any iteration over
+ join_tab record candidates. The function open is called to initiate the
+ process of the iteration. The function next shall read the next record from
+ the set of the record candidates. The record is read into the record buffer
+ of the joined table. The function close shall perform the finalizing actions
+ for the iteration.
+*/
+
+class JOIN_TAB_SCAN_MRR: public JOIN_TAB_SCAN
+{
+ /* Interface object to generate key ranges for MRR */
+ RANGE_SEQ_IF range_seq_funcs;
+
+ /* Number of ranges to be processed by the MRR interface */
+ uint ranges;
+
+ /* Flag to to be passed to the MRR interface */
+ uint mrr_mode;
+
+ /* MRR buffer assotiated with this join cache */
+ HANDLER_BUFFER mrr_buff;
+
+ /* Shall initialize the MRR buffer */
+ virtual void init_mrr_buff()
+ {
+ cache->setup_aux_buffer(mrr_buff);
+ }
+
+public:
+
+ JOIN_TAB_SCAN_MRR(JOIN *j, JOIN_TAB *tab, uint flags, RANGE_SEQ_IF rs_funcs)
+ :JOIN_TAB_SCAN(j, tab), range_seq_funcs(rs_funcs), mrr_mode(flags) {}
+
+ uint aux_buffer_incr(ulong recno);
+
+ int open();
+
+ int next();
+
+ friend class JOIN_CACHE_BKA; /* it needs to add an mrr_mode flag after JOIN_CACHE::init() call */
+};
+
+/*
+ The class JOIN_CACHE_BKA is used when the BKA join algorithm is
+ employed to perform a join operation
+*/
+
+class JOIN_CACHE_BKA :public JOIN_CACHE
+{
+private:
+
+ /* Flag to to be passed to the companion JOIN_TAB_SCAN_MRR object */
+ uint mrr_mode;
+
+ /*
+ This value is set to 1 by the class prepare_look_for_matches method
+ and back to 0 by the class get_next_candidate_for_match method
+ */
+ uint rem_records;
+
+ /*
+ This field contains the current association label set by a call of
+ the multi_range_read_next handler function.
+ See the function JOIN_CACHE_BKA::get_curr_key_association()
+ */
+ uchar *curr_association;
+
+protected:
+
+ /*
+ Get the number of ranges in the cache buffer passed to the MRR
+ interface. For each record its own range is passed.
+ */
+ uint get_number_of_ranges_for_mrr() { return records; }
+
+ /*
+ Setup the MRR buffer as the space between the last record put
+ into the join buffer and the very end of the join buffer
+ */
+ int setup_aux_buffer(HANDLER_BUFFER &aux_buff)
+ {
+ aux_buff.buffer= end_pos;
+ aux_buff.buffer_end= buff+buff_size;
+ return 0;
+ }
+
+ bool prepare_look_for_matches(bool skip_last);
+
+ uchar *get_next_candidate_for_match();
+
+ bool skip_next_candidate_for_match(uchar *rec_ptr);
+
+ void read_next_candidate_for_match(uchar *rec_ptr);
+
+public:
+
+ /*
+ This constructor creates an unlinked BKA join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter.
+ The MRR mode initially is set to 'flags'.
+ */
+ JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags)
+ :JOIN_CACHE(j, tab), mrr_mode(flags) {}
+ /*
+ This constructor creates a linked BKA join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter. The parameter 'prev' specifies the previous
+ cache object to which this cache is linked.
+ The MRR mode initially is set to 'flags'.
+ */
+ JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
+ :JOIN_CACHE(j, tab, prev), mrr_mode(flags) {}
+
+ uchar **get_curr_association_ptr() { return &curr_association; }
+
+ /* Initialize the BKA cache */
+ int init();
+
+ enum Join_algorithm get_join_alg() { return BKA_JOIN_ALG; }
+
+ bool is_key_access() { return TRUE; }
+
+ /* Get the key built over the next record from the join buffer */
+ uint get_next_key(uchar **key);
+
+ /* Check index condition of the joined table for a record from BKA cache */
+ bool skip_index_tuple(char *range_info);
+
+};
+
+
+
+/*
+ The class JOIN_CACHE_BKAH is used when the BKAH join algorithm is
+ employed to perform a join operation
+*/
+
+class JOIN_CACHE_BKAH :public JOIN_CACHE_BNLH
+{
+
+private:
+ /* Flag to to be passed to the companion JOIN_TAB_SCAN_MRR object */
+ uint mrr_mode;
+
+ /*
+ This flag is set to TRUE if the implementation of the MRR interface cannot
+ handle range association labels and does not return them to the caller of
+ the multi_range_read_next handler function. E.g. the implementation of
+ the MRR inteface for the Falcon engine could not return association
+ labels to the caller of multi_range_read_next.
+ The flag is set by JOIN_CACHE_BKA::init() and is not ever changed.
+ */
+ bool no_association;
+
+ /*
+ This field contains the association label returned by the
+ multi_range_read_next function.
+ See the function JOIN_CACHE_BKAH::get_curr_key_association()
+ */
+ uchar *curr_matching_chain;
+
+protected:
+
+ uint get_number_of_ranges_for_mrr() { return key_entries; }
+
+ /*
+ Initialize the MRR buffer allocating some space within the join buffer.
+ The entire space between the last record put into the join buffer and the
+ last key entry added to the hash table is used for the MRR buffer.
+ */
+ int setup_aux_buffer(HANDLER_BUFFER &aux_buff)
+ {
+ aux_buff.buffer= end_pos;
+ aux_buff.buffer_end= last_key_entry;
+ return 0;
+ }
+
+ bool prepare_look_for_matches(bool skip_last);
+
+ /*
+ The implementations of the methods
+ - get_next_candidate_for_match
+ - skip_recurrent_candidate_for_match
+ - read_next_candidate_for_match
+ are inherited from the JOIN_CACHE_BNLH class
+ */
+
+public:
+
+ /*
+ This constructor creates an unlinked BKAH join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter.
+ The MRR mode initially is set to 'flags'.
+ */
+ JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags)
+ :JOIN_CACHE_BNLH(j, tab), mrr_mode(flags) {}
+
+ /*
+ This constructor creates a linked BKAH join cache. The cache is to be
+ used to join table 'tab' to the result of joining the previous tables
+ specified by the 'j' parameter. The parameter 'prev' specifies the previous
+ cache object to which this cache is linked.
+ The MRR mode initially is set to 'flags'.
+ */
+ JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
+ :JOIN_CACHE_BNLH(j, tab, prev), mrr_mode(flags) {}
+
+ uchar **get_curr_association_ptr() { return &curr_matching_chain; }
+
+ /* Initialize the BKAH cache */
+ int init();
+
+ enum Join_algorithm get_join_alg() { return BKAH_JOIN_ALG; }
+
+ /* Check index condition of the joined table for a record from BKAH cache */
+ bool skip_index_tuple(char *range_info);
+};
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 6256a0f89d6..4737b64c94d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1633,11 +1633,14 @@ void st_select_lex::init_query()
nest_level= 0;
link_next= 0;
lock_option= TL_READ_DEFAULT;
+
+ bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
}
void st_select_lex::init_select()
{
st_select_lex_node::init_select();
+ sj_nests.empty();
group_list.empty();
type= db= 0;
having= 0;
@@ -1829,6 +1832,55 @@ void st_select_lex_unit::exclude_tree()
}
+/**
+ Register reference to an item which the subqueries depends on
+
+ @param def_sel select against which the item is resolved
+ @param dependency reference to the item
+
+ @details
+ This function puts the reference dependency to an item that is either an
+ outer field or an aggregate function resolved against an outer select into
+ the list 'depends_on'. It adds it to the 'depends_on' lists for each
+ subquery between this one and 'def_sel' - the subquery against which the
+ item is resolved.
+*/
+
+void st_select_lex::register_dependency_item(st_select_lex *def_sel,
+ Item **dependency)
+{
+ SELECT_LEX *s= this;
+ DBUG_ENTER("st_select_lex::register_dependency_item");
+ DBUG_ASSERT(this != def_sel);
+ DBUG_ASSERT(*dependency);
+ do
+ {
+ /* check duplicates */
+ List_iterator_fast<Item*> li(s->master_unit()->item->depends_on);
+ Item **dep;
+ while ((dep= li++))
+ {
+ if ((*dep)->eq(*dependency, FALSE))
+ {
+ DBUG_PRINT("info", ("dependency %s already present",
+ ((*dependency)->name ?
+ (*dependency)->name :
+ "<no name>")));
+ DBUG_VOID_RETURN;
+ }
+ }
+
+ s->master_unit()->item->depends_on.push_back(dependency);
+ DBUG_PRINT("info", ("depends_on: Select: %d added: %s",
+ s->select_number,
+ ((*dependency)->name ?
+ (*dependency)->name :
+ "<no name>")));
+ } while ((s= s->outer_select()) != def_sel);
+ DBUG_VOID_RETURN;
+}
+
+
/*
st_select_lex_node::mark_as_dependent mark all st_select_lex struct from
this to 'last' as dependent
@@ -1841,9 +1893,8 @@ void st_select_lex_unit::exclude_tree()
'last' should be reachable from this st_select_lex_node
*/
-void st_select_lex::mark_as_dependent(st_select_lex *last, Item *dependency)
+bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last, Item *dependency)
{
- SELECT_LEX *next_to_last;
DBUG_ASSERT(this != last);
@@ -1869,13 +1920,15 @@ void st_select_lex::mark_as_dependent(st_select_lex *last, Item *dependency)
sl->uncacheable|= UNCACHEABLE_UNITED;
}
}
- next_to_last= s;
- } while ((s= s->outer_select()) != last && s != 0);
+ Item_subselect *subquery_expr= s->master_unit()->item;
+ if (subquery_expr && subquery_expr->mark_as_dependent(thd, last,
+ dependency))
+ return TRUE;
+ } while ((s= s->outer_select()) != last && s != 0);
is_correlated= TRUE;
this->master_unit()->item->is_correlated= TRUE;
- if (dependency)
- next_to_last->master_unit()->item->refers_to.push_back(dependency);
+ return FALSE;
}
bool st_select_lex_node::set_braces(bool value) { return 1; }
@@ -2078,16 +2131,28 @@ void st_select_lex::print_limit(THD *thd,
{
SELECT_LEX_UNIT *unit= master_unit();
Item_subselect *item= unit->item;
- if (item && unit->global_parameters == this &&
- (item->substype() == Item_subselect::EXISTS_SUBS ||
- item->substype() == Item_subselect::IN_SUBS ||
- item->substype() == Item_subselect::ALL_SUBS))
+
+ if (item && unit->global_parameters == this)
{
- DBUG_ASSERT(!item->fixed ||
- (select_limit->val_int() == LL(1) && offset_limit == 0));
- return;
+ Item_subselect::subs_type subs_type= item->substype();
+ if (subs_type == Item_subselect::EXISTS_SUBS ||
+ subs_type == Item_subselect::IN_SUBS ||
+ subs_type == Item_subselect::ALL_SUBS)
+ {
+ DBUG_ASSERT(!item->fixed ||
+ /*
+ If not using materialization both:
+ select_limit == 1, and there should be no offset_limit.
+ */
+ (((subs_type == Item_subselect::IN_SUBS) &&
+ ((Item_in_subselect*)item)->exec_method ==
+ Item_in_subselect::MATERIALIZATION) ?
+ TRUE :
+ (select_limit->val_int() == 1LL) &&
+ offset_limit == 0));
+ return;
+ }
}
-
if (explicit_limit)
{
str->append(STRING_WITH_LEN(" limit "));
@@ -2100,6 +2165,7 @@ void st_select_lex::print_limit(THD *thd,
}
}
+
/**
@brief Restore the LEX and THD in case of a parse error.
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 0539de0206d..31ca121ea66 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -566,7 +566,8 @@ public:
bool add_fake_select_lex(THD *thd);
void init_prepare_fake_select_lex(THD *thd);
inline bool is_prepared() { return prepared; }
- bool change_result(select_subselect *result, select_subselect *old_result);
+ bool change_result(select_result_interceptor *result,
+ select_result_interceptor *old_result);
void set_limit(st_select_lex *values);
void set_thd(THD *thd_arg) { thd= thd_arg; }
inline bool is_union ();
@@ -611,6 +612,7 @@ public:
List<TABLE_LIST> top_join_list; /* join list of the top level */
List<TABLE_LIST> *join_list; /* list for the currently parsed join */
TABLE_LIST *embedding; /* table embedding to the above list */
+ List<TABLE_LIST> sj_nests; /* Semi-join nests within this join */
/*
Beginning of the list of leaves in a FROM clause, where the leaves
inlcude all base tables including view tables. The tables are connected
@@ -666,6 +668,11 @@ public:
/* explicit LIMIT clause was used */
bool explicit_limit;
/*
+ This array is used to note whether we have any candidates for
+ expression caching in the corresponding clauses
+ */
+ bool expr_cache_may_be_used[PARSING_PLACE_SIZE];
+ /*
there are subquery in HAVING clause => we can't close tables before
query processing end even if we use temporary table
*/
@@ -753,7 +760,8 @@ public:
}
inline bool is_subquery_function() { return master_unit()->item != 0; }
- void mark_as_dependent(st_select_lex *last, Item *dependency);
+ bool mark_as_dependent(THD *thd, st_select_lex *last, Item *dependency);
+ void register_dependency_item(st_select_lex *last, Item **dependency);
bool set_braces(bool value);
bool inc_in_sum_expr();
@@ -837,7 +845,7 @@ public:
}
void clear_index_hints(void) { index_hints= NULL; }
-
+ bool is_part_of_union() { return master_unit()->is_union(); }
private:
/* current index hint kind. used in filling up index_hints */
enum index_hint_type current_index_hint_type;
diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h
new file mode 100644
index 00000000000..af26f8b5652
--- /dev/null
+++ b/sql/sql_lifo_buffer.h
@@ -0,0 +1,342 @@
+/**
+ @defgroup Bi-directional LIFO buffers used by DS-MRR implementation
+ @{
+*/
+
+class Forward_lifo_buffer;
+class Backward_lifo_buffer;
+
+
+/*
+ A base class for in-memory buffer used by DS-MRR implementation. Common
+ properties:
+ - The buffer is last-in-first-out, i.e. elements that are written last are
+ read first.
+ - The buffer contains fixed-size elements. The elements are either atomic
+ byte sequences or pairs of them.
+ - The buffer resides in the memory provided by the user. It is possible to
+ = dynamically (ie. between write operations) add ajacent memory space to
+ the buffer
+ = dynamically remove unused space from the buffer.
+ The intent of this is to allow to have two buffers on adjacent memory
+ space, one is being read from (and so its space shrinks), while the other
+ is being written to (and so it needs more and more space).
+
+ There are two concrete classes, Forward_lifo_buffer and Backward_lifo_buffer.
+*/
+
+class Lifo_buffer
+{
+protected:
+ size_t size1;
+ size_t size2;
+
+public:
+ /**
+ write() will put into buffer size1 bytes pointed by write_ptr1. If
+ size2!=0, then they will be accompanied by size2 bytes pointed by
+ write_ptr2.
+ */
+ uchar *write_ptr1;
+ uchar *write_ptr2;
+
+ /**
+ read() will do reading by storing pointers to read data into read_ptr1 or
+ into (read_ptr1, read_ptr2), depending on whether the buffer was set to
+ store single objects or pairs.
+ */
+ uchar *read_ptr1;
+ uchar *read_ptr2;
+
+protected:
+ uchar *start; /**< points to start of buffer space */
+ uchar *end; /**< points to just beyond the end of buffer space */
+public:
+
+ enum enum_direction {
+ BACKWARD=-1, /**< buffer is filled/read from bigger to smaller memory addresses */
+ FORWARD=1 /**< buffer is filled/read from smaller to bigger memory addresses */
+ };
+
+ virtual enum_direction type() = 0;
+
+ /* Buffer space control functions */
+
+ /** Let the buffer store data in the given space. */
+ void set_buffer_space(uchar *start_arg, uchar *end_arg)
+ {
+ start= start_arg;
+ end= end_arg;
+ TRASH(start, end - start);
+ reset();
+ }
+
+ /**
+ Specify where write() should get the source data from, as well as source
+ data size.
+ */
+ void setup_writing(size_t len1, size_t len2)
+ {
+ size1= len1;
+ size2= len2;
+ }
+
+ /**
+ Specify where read() should store pointers to read data, as well as read
+ data size. The sizes must match those passed to setup_writing().
+ */
+ void setup_reading(size_t len1, size_t len2)
+ {
+ DBUG_ASSERT(len1 == size1);
+ DBUG_ASSERT(len2 == size2);
+ }
+
+ bool can_write()
+ {
+ return have_space_for(size1 + size2);
+ }
+ virtual void write() = 0;
+
+ bool is_empty() { return used_size() == 0; }
+ virtual bool read() = 0;
+
+ void sort(qsort2_cmp cmp_func, void *cmp_func_arg)
+ {
+ uint elem_size= size1 + size2;
+ uint n_elements= used_size() / elem_size;
+ my_qsort2(used_area(), n_elements, elem_size, cmp_func, cmp_func_arg);
+ }
+
+ virtual void reset() = 0;
+ virtual uchar *end_of_space() = 0;
+protected:
+ virtual size_t used_size() = 0;
+
+ /* To be used only by iterator class: */
+ virtual uchar *get_pos()= 0;
+ virtual bool read(uchar **position, uchar **ptr1, uchar **ptr2)= 0;
+ friend class Lifo_buffer_iterator;
+public:
+ virtual bool have_space_for(size_t bytes) = 0;
+
+ virtual void remove_unused_space(uchar **unused_start, uchar **unused_end)=0;
+ virtual uchar *used_area() = 0;
+ virtual ~Lifo_buffer() {};
+};
+
+
+/**
+ Forward LIFO buffer
+
+ The buffer that is being written to from start to end and read in the
+ reverse. 'pos' points to just beyond the end of used space.
+
+ It is possible to grow/shink the buffer at the end bound
+
+ used space unused space
+ *==============*-----------------*
+ ^ ^ ^
+ | | +--- end
+ | +---- pos
+ +--- start
+*/
+
+class Forward_lifo_buffer: public Lifo_buffer
+{
+ uchar *pos;
+public:
+ enum_direction type() { return FORWARD; }
+ size_t used_size()
+ {
+ return (size_t)(pos - start);
+ }
+ void reset()
+ {
+ pos= start;
+ }
+ uchar *end_of_space() { return pos; }
+ bool have_space_for(size_t bytes)
+ {
+ return (pos + bytes < end);
+ }
+
+ void write()
+ {
+ write_bytes(write_ptr1, size1);
+ if (size2)
+ write_bytes(write_ptr2, size2);
+ }
+ void write_bytes(const uchar *data, size_t bytes)
+ {
+ DBUG_ASSERT(have_space_for(bytes));
+ memcpy(pos, data, bytes);
+ pos += bytes;
+ }
+ bool have_data(uchar *position, size_t bytes)
+ {
+ return ((position - start) >= (ptrdiff_t)bytes);
+ }
+ uchar *read_bytes(uchar **position, size_t bytes)
+ {
+ DBUG_ASSERT(have_data(*position, bytes));
+ *position= (*position) - bytes;
+ return *position;
+ }
+ bool read() { return read(&pos, &read_ptr1, &read_ptr2); }
+ bool read(uchar **position, uchar **ptr1, uchar **ptr2)
+ {
+ if (!have_data(*position, size1 + size2))
+ return TRUE;
+ if (size2)
+ *ptr2= read_bytes(position, size2);
+ *ptr1= read_bytes(position, size1);
+ return FALSE;
+ }
+ void remove_unused_space(uchar **unused_start, uchar **unused_end)
+ {
+ DBUG_ASSERT(0); /* Don't need this yet */
+ }
+ /**
+ Add more space to the buffer. The caller is responsible that the space
+ being added is adjacent to the end of the buffer.
+
+ @param unused_start Start of space
+ @param unused_end End of space
+ */
+ void grow(uchar *unused_start, uchar *unused_end)
+ {
+ DBUG_ASSERT(unused_end >= unused_start);
+ DBUG_ASSERT(end == unused_start);
+ TRASH(unused_start, unused_end - unused_start);
+ end= unused_end;
+ }
+ /* Return pointer to start of the memory area that is occupied by the data */
+ uchar *used_area() { return start; }
+ friend class Lifo_buffer_iterator;
+ uchar *get_pos() { return pos; }
+};
+
+
+
+/**
+ Backward LIFO buffer
+
+ The buffer that is being written to from start to end and read in the
+ reverse. 'pos' points to the start of used space.
+
+ It is possible to grow/shink the buffer at the start.
+
+ unused space used space
+ *--------------*=================*
+ ^ ^ ^
+ | | +--- end
+ | +---- pos
+ +--- start
+*/
+class Backward_lifo_buffer: public Lifo_buffer
+{
+ uchar *pos;
+public:
+ enum_direction type() { return BACKWARD; }
+
+ size_t used_size()
+ {
+ return (size_t)(end - pos);
+ }
+ void reset()
+ {
+ pos= end;
+ }
+ uchar *end_of_space() { return end; }
+ bool have_space_for(size_t bytes)
+ {
+ return (pos - bytes >= start);
+ }
+ void write()
+ {
+ if (write_ptr2)
+ write_bytes(write_ptr2, size2);
+ write_bytes(write_ptr1, size1);
+ }
+ void write_bytes(const uchar *data, size_t bytes)
+ {
+ DBUG_ASSERT(have_space_for(bytes));
+ pos -= bytes;
+ memcpy(pos, data, bytes);
+ }
+ bool read()
+ {
+ return read(&pos, &read_ptr1, &read_ptr2);
+ }
+ bool read(uchar **position, uchar **ptr1, uchar **ptr2)
+ {
+ if (!have_data(*position, size1 + size2))
+ return TRUE;
+ *ptr1= read_bytes(position, size1);
+ if (size2)
+ *ptr2= read_bytes(position, size2);
+ return FALSE;
+ }
+ bool have_data(uchar *position, size_t bytes)
+ {
+ return ((end - position) >= (ptrdiff_t)bytes);
+ }
+ uchar *read_bytes(uchar **position, size_t bytes)
+ {
+ DBUG_ASSERT(have_data(*position, bytes));
+ uchar *ret= *position;
+ *position= *position + bytes;
+ return ret;
+ }
+ /**
+ Stop using/return the unused part of the space
+ @param unused_start OUT Start of the unused space
+ @param unused_end OUT End of the unused space
+ */
+ void remove_unused_space(uchar **unused_start, uchar **unused_end)
+ {
+ *unused_start= start;
+ *unused_end= pos;
+ start= pos;
+ }
+ void grow(uchar *unused_start, uchar *unused_end)
+ {
+ DBUG_ASSERT(0); /* Not used for backward buffers */
+ }
+ /* Return pointer to start of the memory area that is occupied by the data */
+ uchar *used_area() { return pos; }
+ friend class Lifo_buffer_iterator;
+ uchar *get_pos() { return pos; }
+};
+
+
+/** Iterator to walk over contents of the buffer without reading from it */
+class Lifo_buffer_iterator
+{
+ uchar *pos;
+ Lifo_buffer *buf;
+
+public:
+ /* The data is read to here */
+ uchar *read_ptr1;
+ uchar *read_ptr2;
+
+ void init(Lifo_buffer *buf_arg)
+ {
+ buf= buf_arg;
+ pos= buf->get_pos();
+ }
+ /*
+ Read the next value. The calling convention is the same as buf->read()
+ has.
+
+ @retval FALSE - ok
+ @retval TRUE - EOF, reached the end of the buffer
+ */
+ bool read()
+ {
+ return buf->read(&pos, &read_ptr1, &read_ptr2);
+ }
+};
+
+
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index a909335bfa7..21351bd7869 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -604,11 +604,15 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
size_t pl= 0;
List<Item> fv;
Item *item, *val;
- String pfield, pfields;
int n;
const char *tbl= table_name_arg;
const char *tdb= (thd->db != NULL ? thd->db : db_arg);
- String string_buf;
+ char name_buffer[SAFE_NAME_LEN*2];
+ char command_buffer[1024];
+ String string_buf(name_buffer, sizeof(name_buffer),
+ system_charset_info);
+ String pfields(command_buffer, sizeof(command_buffer),
+ system_charset_info);
if (!thd->db || strcmp(db_arg, thd->db))
{
@@ -617,7 +621,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
prefix table name with database name so that it
becomes a FQ name.
*/
- string_buf.set_charset(system_charset_info);
+ string_buf.length(0);
string_buf.append(db_arg);
string_buf.append("`");
string_buf.append(".");
@@ -638,6 +642,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
/*
prepare fields-list and SET if needed; print_query won't do that for us.
*/
+ pfields.length(0);
if (!thd->lex->field_list.is_empty())
{
List_iterator<Item> li(thd->lex->field_list);
@@ -682,8 +687,8 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
}
}
- p= pfields.c_ptr_safe();
- pl= strlen(p);
+ p= pfields.c_ptr_safe();
+ pl= pfields.length();
if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
return TRUE;
@@ -970,7 +975,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
((Field_timestamp*) field)->set_time();
/*
- QQ: We probably should not throw warning for each field.
+ TODO: We probably should not throw warning for each field.
But how about intention to always have the same number
of warnings in THD::cuted_fields (and get rid of cuted_fields
in the end ?)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 0cbccf3bedd..2482775d5cd 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -28,6 +28,7 @@
#include "events.h"
#include "sql_trigger.h"
#include "debug_sync.h"
+#include "sql_handler.h"
#ifdef WITH_ARIA_STORAGE_ENGINE
#include "../storage/maria/ha_maria.h"
@@ -1199,6 +1200,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
general_log_write(thd, command, thd->query(), thd->query_length());
DBUG_PRINT("query",("%-.4096s",thd->query()));
+
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.set_query_source(thd->query(), thd->query_length());
#endif
@@ -1350,54 +1352,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
error=TRUE; // End server
break;
-#ifdef REMOVED
- case COM_CREATE_DB: // QQ: To be removed
- {
- LEX_STRING db, alias;
- HA_CREATE_INFO create_info;
-
- status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
- if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
- thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
- check_db_name(&db))
- {
- my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
- break;
- }
- if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
- is_schema_db(db.str, db.length)))
- break;
- general_log_print(thd, command, "%.*s", db.length, db.str);
- bzero(&create_info, sizeof(create_info));
- mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
- &create_info, 0);
- break;
- }
- case COM_DROP_DB: // QQ: To be removed
- {
- status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
- LEX_STRING db;
-
- if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
- check_db_name(&db))
- {
- my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
- break;
- }
- if (check_access(thd, DROP_ACL, db.str, 0, 1, 0,
- is_schema_db(db.str, db.length)))
- break;
- if (thd->locked_tables || thd->active_transaction())
- {
- my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
- ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
- break;
- }
- general_log_write(thd, command, "%.*s", db.length, db.str);
- mysql_rm_db(thd, db.str, 0, 0);
- break;
- }
-#endif
#ifndef EMBEDDED_LIBRARY
case COM_BINLOG_DUMP:
{
@@ -5084,6 +5038,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
param->select_limit=
new Item_int((ulonglong) thd->variables.select_limit);
}
+ thd->thd_marker.emb_on_expr_nest= NULL;
if (!(res= open_and_lock_tables(thd, all_tables)))
{
if (lex->describe)
@@ -5104,9 +5059,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
thd->lex->unit.print(&str, QT_ORDINARY);
- str.append('\0');
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_YES, str.ptr());
+ ER_YES, str.c_ptr_safe());
}
if (res)
result->abort();
@@ -5857,6 +5811,7 @@ void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat)
thd->query_plan_flags= QPLAN_INIT;
thd->query_plan_fsort_passes= 0;
+ thd->thd_marker.emb_on_expr_nest= NULL;
/*
Because we come here only for start of top-statements, binlog format is
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index dd908e1b60e..58cc7dc93a9 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -303,7 +303,7 @@ static const char *item_val_str(struct st_mysql_value *value,
Lets be nice and create a temporary string since the
buffer was too small
*/
- return current_thd->strmake(res->c_ptr_quick(), res->length());
+ return current_thd->strmake(res->ptr(), res->length());
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 98434439998..8a9870e2865 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -95,6 +95,7 @@ When one supplies long data for a placeholder:
#else
#include <mysql_com.h>
#endif
+#include "sql_handler.h"
/**
A result class used to send cursor rows using the binary protocol.
@@ -243,6 +244,8 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
int error;
THD *thd= stmt->thd;
DBUG_ENTER("send_prep_stmt");
+ DBUG_PRINT("enter",("stmt->id: %lu columns: %d param_count: %d",
+ stmt->id, columns, stmt->param_count));
buff[0]= 0; /* OK packet indicator */
int4store(buff+1, stmt->id);
@@ -1385,6 +1388,7 @@ static int mysql_test_select(Prepared_statement *stmt,
goto error;
thd->used_tables= 0; // Updated by setup_fields
+ thd->thd_marker.emb_on_expr_nest= 0;
/*
JOIN::prepare calls
@@ -1834,6 +1838,56 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
return res;
}
+/**
+ Validate SELECT statement.
+
+ In case of success, if this query is not EXPLAIN, send column list info
+ back to the client.
+
+ @param stmt prepared statement
+ @param tables list of tables used in the query
+
+ @retval 0 success
+ @retval 1 error, error message is set in THD
+ @retval 2 success, and statement metadata has been sent
+*/
+
+static int mysql_test_handler_read(Prepared_statement *stmt,
+ TABLE_LIST *tables)
+{
+ THD *thd= stmt->thd;
+ LEX *lex= stmt->lex;
+ SQL_HANDLER *ha_table;
+ DBUG_ENTER("mysql_test_select");
+
+ lex->select_lex.context.resolve_in_select_list= TRUE;
+
+ /*
+ We don't have to test for permissions as this is already done during
+ HANDLER OPEN
+ */
+ if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode,
+ lex->ident.str,
+ lex->insert_list,
+ lex->select_lex.where)))
+ DBUG_RETURN(1);
+
+ if (!stmt->is_sql_prepare())
+ {
+ if (!lex->result && !(lex->result= new (stmt->mem_root) select_send))
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send));
+ DBUG_RETURN(1);
+ }
+ if (send_prep_stmt(stmt, ha_table->fields.elements) ||
+ lex->result->send_fields(ha_table->fields, Protocol::SEND_EOF) ||
+ thd->protocol->flush())
+ DBUG_RETURN(1);
+ DBUG_RETURN(2);
+ }
+ DBUG_RETURN(0);
+}
+
/**
Perform semantic analysis of the parsed tree and send a response packet
@@ -1948,6 +2002,14 @@ static bool check_prepared_statement(Prepared_statement *stmt)
res= mysql_test_insert_select(stmt, tables);
break;
+ case SQLCOM_HA_READ:
+ res= mysql_test_handler_read(stmt, tables);
+ {
+ /* Statement and field info has already been sent */
+ DBUG_RETURN(FALSE);
+ }
+ break;
+
/*
Note that we don't need to have cases in this list if they are
marked with CF_STATUS_COMMAND in sql_command_flags
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index e85e730db5b..5c8d1add04b 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -19,7 +19,7 @@
#include "mysql_priv.h"
#include "sql_trigger.h"
-
+#include "sql_handler.h"
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
bool skip_error);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6f5a8dceb10..ea2ba6e96eb 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -32,17 +32,18 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include "sql_cursor.h"
+#include "opt_subselect.h"
#include <m_ctype.h>
#include <my_bit.h>
#include <hash.h>
#include <ft_global.h>
-#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
-#include "../storage/maria/ha_maria.h"
-#define TMP_ENGINE_HTON maria_hton
-#else
-#define TMP_ENGINE_HTON myisam_hton
-#endif
+//#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+//#include "../storage/maria/ha_maria.h"
+//#define TMP_ENGINE_HTON maria_hton
+//#else
+//#define TMP_ENGINE_HTON myisam_hton
+//#endif
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext",
@@ -64,11 +65,12 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
table_map used_tables);
-static bool choose_plan(JOIN *join,table_map join_tables);
+bool choose_plan(JOIN *join,table_map join_tables);
-static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
- table_map remaining_tables, uint idx,
- double record_count, double read_time);
+void best_access_path(JOIN *join, JOIN_TAB *s,
+ table_map remaining_tables, uint idx,
+ bool disable_jbuf, double record_count,
+ POSITION *pos, POSITION *loose_scan_pos);
static void optimize_straight_join(JOIN *join, table_map join_tables);
static bool greedy_search(JOIN *join, table_map remaining_tables,
uint depth, uint prune_level);
@@ -78,8 +80,9 @@ static bool best_extension_by_limited_search(JOIN *join,
double read_time, uint depth,
uint prune_level);
static uint determine_search_depth(JOIN* join);
-static int join_tab_cmp(const void* ptr1, const void* ptr2);
-static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
+static int join_tab_cmp(const void *dummy, const void* ptr1, const void* ptr2);
+static int join_tab_cmp_straight(const void *dummy, const void* ptr1, const void* ptr2);
+static int join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void *ptr2);
/*
TODO: 'find_best' is here only temporarily until 'greedy_search' is
tested and approved.
@@ -94,8 +97,11 @@ static store_key *get_store_key(THD *thd,
KEY_PART_INFO *key_part, uchar *key_buff,
uint maybe_null);
static void make_outerjoin_info(JOIN *join);
+static Item*
+make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables, table_map sjm_tables);
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
-static void make_join_readinfo(JOIN *join, ulonglong options);
+static void revise_cache_usage(JOIN_TAB *join_tab);
+static bool make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after);
static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables);
static void update_depend_map(JOIN *join);
static void update_depend_map(JOIN *join, ORDER *order);
@@ -113,7 +119,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
COND_EQUAL *cond_equal,
void *table_join_idx);
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
- COND *conds, bool top);
+ COND *conds, bool top, bool in_sj);
static bool check_interleaving_with_nj(JOIN_TAB *next);
static void restore_prev_nj_state(JOIN_TAB *last);
static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list);
@@ -122,16 +128,12 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
static COND *optimize_cond(JOIN *join, COND *conds,
List<TABLE_LIST> *join_list,
- Item::cond_result *cond_value);
+ Item::cond_result *cond_value,
+ COND_EQUAL **cond_equal);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
-static bool open_tmp_table(TABLE *table);
-static bool create_internal_tmp_table(TABLE *,TMP_TABLE_PARAM *, ulonglong);
-static bool create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
- TMP_TABLE_PARAM *param,
- int error,
- bool ignore_last_dupp,
- handlerton *hton,
- const char *proc_info);
+static bool create_internal_tmp_table_from_heap2(THD *, TABLE *,
+ ENGINE_COLUMNDEF *, ENGINE_COLUMNDEF **,
+ int, bool, handlerton *, const char *);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
@@ -141,10 +143,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
static enum_nested_loop_state
evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
static enum_nested_loop_state
-flush_cached_records(JOIN *join, JOIN_TAB *join_tab, bool skip_last);
-static enum_nested_loop_state
end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-static enum_nested_loop_state
+enum_nested_loop_state
end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_write(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
@@ -152,7 +152,7 @@ static enum_nested_loop_state
end_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-static enum_nested_loop_state
+enum_nested_loop_state
end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static int test_if_group_changed(List<Cached_item> &list);
@@ -167,7 +167,7 @@ static int join_no_more_records(READ_RECORD *info);
static int join_read_next(READ_RECORD *info);
static int join_init_quick_read_record(JOIN_TAB *tab);
static int test_if_quick_select(JOIN_TAB *tab);
-static int join_init_read_record(JOIN_TAB *tab);
+static bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab);
static int join_read_first(JOIN_TAB *tab);
static int join_read_next(READ_RECORD *info);
static int join_read_next_same(READ_RECORD *info);
@@ -178,13 +178,21 @@ static int join_ft_read_first(JOIN_TAB *tab);
static int join_ft_read_next(READ_RECORD *info);
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(COND *cond,table_map table,
- table_map used_table);
+static COND *make_cond_for_table(Item *cond,table_map table,
+ table_map used_table,
+ bool exclude_expensive_cond,
+ bool retain_ref_cond);
+static COND *make_cond_for_table_from_pred(Item *root_cond, Item *cond,
+ table_map tables,
+ table_map used_table,
+ bool exclude_expensive_cond,
+ bool retain_ref_cond);
+
static Item* part_of_refkey(TABLE *form,Field *field);
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
ha_rows select_limit, bool no_changes,
- key_map *map);
+ const key_map *map);
static bool list_contains_unique_index(TABLE *table,
bool (*find_func) (Field *, void *), void *data);
static bool find_field_in_item_list (Field *field, void *data);
@@ -198,15 +206,8 @@ static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
ulong offset,Item *having);
static int remove_dup_with_hash_index(THD *thd,TABLE *table,
uint field_count, Field **first_field,
-
ulong key_length,Item *having);
-static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
-static ulong used_blob_length(CACHE_FIELD **ptr);
-static bool store_record_in_cache(JOIN_CACHE *cache);
-static void reset_cache_read(JOIN_CACHE *cache);
-static void reset_cache_write(JOIN_CACHE *cache);
-static void read_cached_record(JOIN_TAB *tab);
-static bool cmp_buffer_with_ref(JOIN_TAB *tab);
+static bool cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref);
static bool setup_new_fields(THD *thd, List<Item> &fields,
List<Item> &all_fields, ORDER *new_order);
static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
@@ -237,10 +238,15 @@ static bool init_sum_functions(Item_sum **func, Item_sum **end);
static bool update_sum_func(Item_sum **func);
static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
bool distinct, const char *message=NullS);
-static Item *remove_additional_cond(Item* conds);
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
-static bool test_if_ref(Item_field *left_item,Item *right_item);
+void get_partial_join_cost(JOIN *join, uint idx, double *read_time_arg,
+ double *record_count_arg);
+static uint make_join_orderinfo(JOIN *join);
+static int
+join_read_record_no_init(JOIN_TAB *tab);
+Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
+ bool *inherited_fl);
/**
This handles SELECT with and without UNION.
@@ -461,6 +467,7 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
mysql_select assumes that all tables are already opened
*****************************************************************************/
+
/**
Prepare of whole select (including sub queries in future).
@@ -547,24 +554,13 @@ JOIN::prepare(Item ***rref_pointer_array,
DBUG_RETURN(-1); /* purecov: inspected */
thd->lex->allow_sum_func= save_allow_sum_func;
}
-
- if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE))
- {
- Item_subselect *subselect;
- /* Is it subselect? */
- if ((subselect= select_lex->master_unit()->item))
- {
- Item_subselect::trans_res res;
- if ((res= subselect->select_transformer(this)) !=
- Item_subselect::RES_OK)
- {
- select_lex->fix_prepare_information(thd, &conds, &having);
- DBUG_RETURN((res == Item_subselect::RES_ERROR));
- }
- }
- }
+
+ int res= check_and_do_in_subquery_rewrites(this);
select_lex->fix_prepare_information(thd, &conds, &having);
+
+ if (res)
+ DBUG_RETURN(res);
if (order)
{
@@ -731,88 +727,6 @@ err:
}
-/*
- Remove the predicates pushed down into the subquery
-
- SYNOPSIS
- JOIN::remove_subq_pushed_predicates()
- where IN Must be NULL
- OUT The remaining WHERE condition, or NULL
-
- DESCRIPTION
- Given that this join will be executed using (unique|index)_subquery,
- without "checking NULL", remove the predicates that were pushed down
- into the subquery.
-
- If the subquery compares scalar values, we can remove the condition that
- was wrapped into trig_cond (it will be checked when needed by the subquery
- engine)
-
- If the subquery compares row values, we need to keep the wrapped
- equalities in the WHERE clause: when the left (outer) tuple has both NULL
- and non-NULL values, we'll do a full table scan and will rely on the
- equalities corresponding to non-NULL parts of left tuple to filter out
- non-matching records.
-
- TODO: We can remove the equalities that will be guaranteed to be true by the
- fact that subquery engine will be using index lookup. This must be done only
- for cases where there are no conversion errors of significance, e.g. 257
- that is searched in a byte. But this requires homogenization of the return
- codes of all Field*::store() methods.
-*/
-
-void JOIN::remove_subq_pushed_predicates(Item **where)
-{
- if (conds->type() == Item::FUNC_ITEM &&
- ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
- ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
- ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
- test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
- ((Item_func *)conds)->arguments()[0]))
- {
- *where= 0;
- return;
- }
-}
-
-
-/*
- Index lookup-based subquery: save some flags for EXPLAIN output
-
- SYNOPSIS
- save_index_subquery_explain_info()
- join_tab Subquery's join tab (there is only one as index lookup is
- only used for subqueries that are single-table SELECTs)
- where Subquery's WHERE clause
-
- DESCRIPTION
- For index lookup-based subquery (i.e. one executed with
- subselect_uniquesubquery_engine or subselect_indexsubquery_engine),
- check its EXPLAIN output row should contain
- "Using index" (TAB_INFO_FULL_SCAN_ON_NULL)
- "Using Where" (TAB_INFO_USING_WHERE)
- "Full scan on NULL key" (TAB_INFO_FULL_SCAN_ON_NULL)
- and set appropriate flags in join_tab->packed_info.
-*/
-
-static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
-{
- join_tab->packed_info= TAB_INFO_HAVE_VALUE;
- if (join_tab->table->covering_keys.is_set(join_tab->ref.key))
- join_tab->packed_info |= TAB_INFO_USING_INDEX;
- if (where)
- join_tab->packed_info |= TAB_INFO_USING_WHERE;
- for (uint i = 0; i < join_tab->ref.key_parts; i++)
- {
- if (join_tab->ref.cond_guards[i])
- {
- join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
- break;
- }
- }
-}
-
-
/**
global select optimisation.
@@ -828,6 +742,9 @@ static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
int
JOIN::optimize()
{
+ ulonglong select_opts_for_readinfo;
+ uint no_jbuf_after;
+
DBUG_ENTER("JOIN::optimize");
// to prevent double initialization on EXPLAIN
if (optimized)
@@ -835,6 +752,12 @@ JOIN::optimize()
optimized= 1;
thd_proc_info(thd, "optimizing");
+
+ /* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
+ if (convert_join_subqueries_to_semijoins(this))
+ DBUG_RETURN(1); /* purecov: inspected */
+ /* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
+
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
unit->select_limit_cnt);
/* select_limit is used to decide if we are likely to scan the whole table */
@@ -884,7 +807,7 @@ JOIN::optimize()
sel->first_cond_optimization= 0;
/* Convert all outer joins to inner joins if possible */
- conds= simplify_joins(this, join_list, conds, TRUE);
+ conds= simplify_joins(this, join_list, conds, TRUE, FALSE);
build_bitmap_for_nested_joins(join_list, 0);
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
@@ -893,7 +816,7 @@ JOIN::optimize()
thd->restore_active_arena(arena, &backup);
}
- conds= optimize_cond(this, conds, join_list, &cond_value);
+ conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
if (thd->is_error())
{
error= 1;
@@ -902,7 +825,7 @@ JOIN::optimize()
}
{
- having= optimize_cond(this, having, join_list, &having_value);
+ having= optimize_cond(this, having, join_list, &having_value, &having_equal);
if (thd->is_error())
{
error= 1;
@@ -923,7 +846,7 @@ JOIN::optimize()
"Impossible HAVING" : "Impossible WHERE";
tables= 0;
error= 0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
}
@@ -973,7 +896,7 @@ JOIN::optimize()
zero_result_cause= "No matching min/max row";
tables= 0;
error=0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
if (res > 1)
{
@@ -987,7 +910,7 @@ JOIN::optimize()
zero_result_cause= "No matching min/max row";
tables= 0;
error=0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
@@ -1006,19 +929,23 @@ JOIN::optimize()
if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
{
COND *table_independent_conds=
- make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0);
+ make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, FALSE, FALSE);
DBUG_EXECUTE("where",
print_where(table_independent_conds,
"where after opt_sum_query()",
QT_ORDINARY););
conds= table_independent_conds;
}
+ goto setup_subq_exit;
}
}
if (!tables_list)
{
DBUG_PRINT("info",("No tables"));
error= 0;
+ /* Create all structures needed for materialized subquery execution. */
+ if (setup_subquery_materialization())
+ DBUG_RETURN(1);
DBUG_RETURN(0);
}
error= -1; // Error is sent to client
@@ -1062,7 +989,7 @@ JOIN::optimize()
zero_result_cause= "no matching row in const table";
DBUG_PRINT("error",("Error: %s", zero_result_cause));
error= 0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
if (!(thd->options & OPTION_BIG_SELECTS) &&
best_read > (double) thd->variables.max_join_size &&
@@ -1133,7 +1060,7 @@ JOIN::optimize()
{
zero_result_cause=
"Impossible WHERE noticed after reading const tables";
- DBUG_RETURN(0); // error == 0
+ goto setup_subq_exit;
}
error= -1; /* if goto err */
@@ -1354,76 +1281,38 @@ JOIN::optimize()
test(select_options & OPTION_BUFFER_RESULT))) ||
(rollup.state != ROLLUP::STATE_NONE && select_distinct));
- // No cache for MATCH
- make_join_readinfo(this,
- (select_options & (SELECT_DESCRIBE |
- SELECT_NO_JOIN_CACHE)) |
- (select_lex->ftfunc_list->elements ?
- SELECT_NO_JOIN_CACHE : 0));
+ /*
+ If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
+ whose columns are required to be returned in a sorted order, then
+ the proper value for no_jbuf_after should be yielded by a call to
+ the make_join_orderinfo function.
+ Yet the current implementation of FORCE INDEX hints does not
+ allow us to do it in a clean manner.
+ */
+ no_jbuf_after= 1 ? tables : make_join_orderinfo(this);
+
+ select_opts_for_readinfo=
+ (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) |
+ (select_lex->ftfunc_list->elements ? SELECT_NO_JOIN_CACHE : 0);
+
+ // No cache for MATCH == 'Don't use join buffering when we use MATCH'.
+ if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
+ DBUG_RETURN(1);
/* Perform FULLTEXT search before all regular searches */
if (!(select_options & SELECT_DESCRIBE))
init_ftfuncs(thd, select_lex, test(order));
- /*
- is this simple IN subquery?
- */
- if (!group_list && !order &&
- unit->item && unit->item->substype() == Item_subselect::IN_SUBS &&
- tables == 1 && conds &&
- !unit->is_union())
- {
- if (!having)
- {
- Item *where= conds;
- if (join_tab[0].type == JT_EQ_REF &&
- join_tab[0].ref.items[0]->name == in_left_expr_name)
- {
- remove_subq_pushed_predicates(&where);
- save_index_subquery_explain_info(join_tab, where);
- join_tab[0].type= JT_UNIQUE_SUBQUERY;
- error= 0;
- DBUG_RETURN(unit->item->
- change_engine(new
- subselect_uniquesubquery_engine(thd,
- join_tab,
- unit->item,
- where)));
- }
- else if (join_tab[0].type == JT_REF &&
- join_tab[0].ref.items[0]->name == in_left_expr_name)
- {
- remove_subq_pushed_predicates(&where);
- save_index_subquery_explain_info(join_tab, where);
- join_tab[0].type= JT_INDEX_SUBQUERY;
- error= 0;
- DBUG_RETURN(unit->item->
- change_engine(new
- subselect_indexsubquery_engine(thd,
- join_tab,
- unit->item,
- where,
- NULL,
- 0)));
- }
- } else if (join_tab[0].type == JT_REF_OR_NULL &&
- join_tab[0].ref.items[0]->name == in_left_expr_name &&
- having->name == in_having_cond)
- {
- join_tab[0].type= JT_INDEX_SUBQUERY;
- error= 0;
- conds= remove_additional_cond(conds);
- save_index_subquery_explain_info(join_tab, conds);
- DBUG_RETURN(unit->item->
- change_engine(new subselect_indexsubquery_engine(thd,
- join_tab,
- unit->item,
- conds,
- having,
- 1)));
- }
+ /* Create all structures needed for materialized subquery execution. */
+ if (setup_subquery_materialization())
+ DBUG_RETURN(1);
+
+ int res;
+ if ((res= rewrite_to_index_subquery_engine(this)) != -1)
+ DBUG_RETURN(res);
+ if (setup_subquery_caches())
+ DBUG_RETURN(-1);
- }
/*
Need to tell handlers that to play it safe, it should fetch all
columns of the primary key of the tables: this is because MySQL may
@@ -1487,7 +1376,7 @@ JOIN::optimize()
for (ORDER *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
{
Item *item= *tmp_order->item;
- if (item->walk(&Item::is_expensive_processor, 0, (uchar*)0))
+ if (item->is_expensive())
{
/* Force tmp table without sort */
need_tmp=1; simple_order=simple_group=0;
@@ -1639,6 +1528,109 @@ JOIN::optimize()
error= 0;
DBUG_RETURN(0);
+
+setup_subq_exit:
+ /*
+ Even with zero matching rows, subqueries in the HAVING clause may
+ need to be evaluated if there are aggregate functions in the
+ query. If we have planned to materialize the subquery, we need to
+ set it up properly before prematurely leaving optimize().
+ */
+ if (setup_subquery_materialization())
+ DBUG_RETURN(1);
+ error= 0;
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Setup expression caches for subqueries that need them
+
+ @details
+ The function wraps correlated subquery expressions that return one value
+ into objects of the class Item_cache_wrapper setting up an expression
+ cache for each of them. The result values of the subqueries are to be
+ cached together with the corresponding sets of the parameters - outer
+ references of the subqueries.
+
+ @retval FALSE OK
+ @retval TRUE Error
+*/
+
+bool JOIN::setup_subquery_caches()
+{
+ DBUG_ENTER("JOIN::setup_subquery_caches");
+
+ /*
+ We have to check all this condition together because items created in
+ one of this clauses can be moved to another one by optimizer
+ */
+ if (select_lex->expr_cache_may_be_used[IN_WHERE] ||
+ select_lex->expr_cache_may_be_used[IN_HAVING] ||
+ select_lex->expr_cache_may_be_used[IN_ON] ||
+ select_lex->expr_cache_may_be_used[NO_MATTER])
+ {
+ if (conds)
+ conds= conds->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+ for (JOIN_TAB *tab= join_tab + const_tables;
+ tab < join_tab + tables ;
+ tab++)
+ {
+ if (tab->select_cond)
+ tab->select_cond=
+ tab->select_cond->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+ if (tab->cache_select && tab->cache_select->cond)
+ tab->cache_select->cond=
+ tab->cache_select->
+ cond->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+
+ }
+
+ if (having)
+ having= having->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+ if (tmp_having)
+ {
+ DBUG_ASSERT(having == NULL);
+ tmp_having= tmp_having->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+ }
+ }
+ if (select_lex->expr_cache_may_be_used[SELECT_LIST] ||
+ select_lex->expr_cache_may_be_used[IN_GROUP_BY] ||
+ select_lex->expr_cache_may_be_used[NO_MATTER])
+ {
+ List_iterator<Item> li(all_fields);
+ Item *item;
+ while ((item= li++))
+ {
+ Item *new_item=
+ item->transform(&Item::expr_cache_insert_transformer, (uchar*) thd);
+ if (new_item != item)
+ {
+ thd->change_item_tree(li.ref(), new_item);
+ }
+ }
+ for (ORDER *group= group_list; group ; group= group->next)
+ {
+ *group->item=
+ (*group->item)->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+ }
+ }
+ if (select_lex->expr_cache_may_be_used[NO_MATTER])
+ {
+ for (ORDER *ord= order; ord; ord= ord->next)
+ {
+ *ord->item=
+ (*ord->item)->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
+ }
+ }
+ DBUG_RETURN(FALSE);
}
@@ -1651,6 +1643,62 @@ void JOIN::restore_tmp()
}
+/*
+ Shrink join buffers used for preceding tables to reduce the occupied space
+
+ SYNOPSIS
+ shrink_join_buffers()
+ jt table up to which the buffers are to be shrunk
+ curr_space the size of the space used by the buffers for tables 1..jt
+ needed_space the size of the space that has to be used by these buffers
+
+ DESCRIPTION
+ The function makes an attempt to shrink all join buffers used for the
+ tables starting from the first up to jt to reduce the total size of the
+ space occupied by the buffers used for tables 1,...,jt from curr_space
+ to needed_space.
+ The function assumes that the buffer for the table jt has not been
+ allocated yet.
+
+ RETURN
+ FALSE if all buffer have been successfully shrunk
+ TRUE otherwise
+*/
+
+bool JOIN::shrink_join_buffers(JOIN_TAB *jt,
+ ulonglong curr_space,
+ ulonglong needed_space)
+{
+ JOIN_CACHE *cache;
+ for (JOIN_TAB *tab= join_tab+const_tables; tab < jt; tab++)
+ {
+ cache= tab->cache;
+ if (cache)
+ {
+ ulong buff_size;
+ if (needed_space < cache->get_min_join_buffer_size())
+ return TRUE;
+ if (cache->shrink_join_buffer_in_ratio(curr_space, needed_space))
+ {
+ revise_cache_usage(tab);
+ return TRUE;
+ }
+ buff_size= cache->get_join_buffer_size();
+ curr_space-= buff_size;
+ needed_space-= buff_size;
+ }
+ }
+
+ cache= jt->cache;
+ DBUG_ASSERT(cache);
+ if (needed_space < cache->get_min_join_buffer_size())
+ return TRUE;
+ cache->set_join_buffer_size(needed_space);
+
+ return FALSE;
+}
+
+
int
JOIN::reinit()
{
@@ -1676,6 +1724,7 @@ JOIN::reinit()
free_io_cache(exec_tmp_table2);
filesort_free_buffers(exec_tmp_table2,0);
}
+ clear_sj_tmp_tables(this);
if (items0)
set_items_ref_array(items0);
@@ -1918,7 +1967,10 @@ JOIN::exec()
DBUG_PRINT("info", ("%s", thd->proc_info));
if (!curr_join->sort_and_group &&
curr_join->const_tables != curr_join->tables)
- curr_join->join_tab[curr_join->const_tables].sorted= 0;
+ {
+ JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables;
+ first_tab->sorted= test(first_tab->loosescan_match_tab);
+ }
if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
{
error= tmp_error;
@@ -2086,7 +2138,10 @@ JOIN::exec()
curr_join->group_list= 0;
if (!curr_join->sort_and_group &&
curr_join->const_tables != curr_join->tables)
- curr_join->join_tab[curr_join->const_tables].sorted= 0;
+ {
+ JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables;
+ first_tab->sorted= test(first_tab->loosescan_match_tab);
+ }
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
0)))
@@ -2213,7 +2268,7 @@ JOIN::exec()
Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having,
used_tables,
- (table_map) 0);
+ (table_map)0, FALSE, FALSE);
if (sort_table_cond)
{
if (!curr_table->select)
@@ -2229,14 +2284,22 @@ JOIN::exec()
DBUG_VOID_RETURN;
curr_table->select->cond->fix_fields(thd, 0);
}
- curr_table->select_cond= curr_table->select->cond;
+ if (curr_table->pre_idx_push_select_cond)
+ {
+ if (!(curr_table->pre_idx_push_select_cond=
+ new Item_cond_and(curr_table->pre_idx_push_select_cond,
+ sort_table_cond)))
+ DBUG_VOID_RETURN;
+ curr_table->pre_idx_push_select_cond->fix_fields(thd, 0);
+ }
+ 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,
"select and having",
QT_ORDINARY););
curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
~ (table_map) 0,
- ~used_tables);
+ ~used_tables, FALSE, FALSE);
DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
"having after sort",
QT_ORDINARY););
@@ -2394,6 +2457,7 @@ JOIN::destroy()
DBUG_RETURN(tmp_join->destroy());
}
cond_equal= 0;
+ having_equal= 0;
cleanup(1);
/* Cleanup items referencing temporary table columns */
@@ -2404,6 +2468,7 @@ JOIN::destroy()
if (exec_tmp_table2)
free_tmp_table(thd, exec_tmp_table2);
delete select;
+ destroy_sj_tmp_tables(this);
delete_dynamic(&keyuse);
delete procedure;
DBUG_RETURN(error);
@@ -2581,6 +2646,52 @@ err:
DBUG_RETURN(join->error);
}
+
+/**
+ Setup for execution all subqueries of a query, for which the optimizer
+ chose hash semi-join.
+
+ @details Iterate over all subqueries of the query, and if they are under an
+ IN predicate, and the optimizer chose to compute it via hash semi-join:
+ - try to initialize all data structures needed for the materialized execution
+ of the IN predicate,
+ - if this fails, then perform the IN=>EXISTS transformation which was
+ previously blocked during JOIN::prepare.
+
+ This method is part of the "code generation" query processing phase.
+
+ This phase must be called after substitute_for_best_equal_field() because
+ that function may replace items with other items from a multiple equality,
+ and we need to reference the correct items in the index access method of the
+ IN predicate.
+
+ @return Operation status
+ @retval FALSE success.
+ @retval TRUE error occurred.
+*/
+
+bool JOIN::setup_subquery_materialization()
+{
+ for (SELECT_LEX_UNIT *un= select_lex->first_inner_unit(); un;
+ un= un->next_unit())
+ {
+ for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
+ {
+ Item_subselect *subquery_predicate= sl->master_unit()->item;
+ if (subquery_predicate &&
+ subquery_predicate->substype() == Item_subselect::IN_SUBS)
+ {
+ Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
+ if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
+ in_subs->setup_engine())
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
/*****************************************************************************
Create JOIN_TABS, make a guess about the table types,
Approximate how many records will be used in each table
@@ -2602,7 +2713,7 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
select->head=table;
table->reginfo.impossible_range=0;
if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
- limit, 0)) == 1)
+ limit, 0, FALSE)) == 1)
DBUG_RETURN(select->quick->records);
if (error == -1)
{
@@ -2628,6 +2739,7 @@ typedef struct st_sargable_param
uint num_values; /* number of values in the above array */
} SARGABLE_PARAM;
+
/**
Calculate the best possible join and initialize the join structure.
@@ -2722,7 +2834,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
s->embedding_map|= embedding->nested_join->nj_map;
continue;
}
- if (embedding)
+ if (embedding && !(embedding->sj_on_expr && ! embedding->embedding))
{
/* s belongs to a nested join, maybe to several embedded joins */
s->embedding_map= 0;
@@ -2919,7 +3031,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
{
start_keyuse=keyuse;
key=keyuse->key;
- s->keys.set_bit(key); // QQ: remove this ?
+ s->keys.set_bit(key); // TODO: remove this ?
refs=0;
const_ref.clear_all();
@@ -2937,9 +3049,16 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
keyuse++;
} while (keyuse->table == table && keyuse->key == key);
+ TABLE_LIST *embedding= table->pos_in_table_list->embedding;
+ /*
+ TODO (low priority): currently we ignore the const tables that
+ are within a semi-join nest which is within an outer join nest.
+ The effect of this is that we don't do const substitution for
+ such tables.
+ */
if (eq_part.is_prefix(table->key_info[key].key_parts) &&
!table->fulltext_searched &&
- !table->pos_in_table_list->embedding)
+ (!embedding || (embedding->sj_on_expr && !embedding->embedding)))
{
if (table->key_info[key].flags & HA_NOSAME)
{
@@ -2973,7 +3092,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
}
}
} while (join->const_table_map & found_ref && ref_changed);
-
+
/*
Update info on indexes that can be used for search lookups as
reading const tables may has added new sargable predicates.
@@ -3023,9 +3142,16 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
all select distinct fields participate in one index.
*/
add_group_and_distinct_keys(join, s);
-
- if (!s->const_keys.is_clear_all() &&
- !s->table->pos_in_table_list->embedding)
+
+ /*
+ Perform range analysis if there are keys it could use (1).
+ Don't do range analysis if we're on the inner side of an outer join (2).
+ Do range analysis if we're on the inner side of a semi-join (3).
+ */
+ if (!s->const_keys.is_clear_all() && // (1)
+ (!s->table->pos_in_table_list->embedding || // (2)
+ (s->table->pos_in_table_list->embedding && // (3)
+ s->table->pos_in_table_list->embedding->sj_on_expr))) // (3)
{
ha_rows records;
SQL_SELECT *select;
@@ -3069,16 +3195,24 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
}
}
+ if (pull_out_semijoin_tables(join))
+ DBUG_RETURN(TRUE);
+
join->join_tab=stat;
join->map2table=stat_ref;
join->table= join->all_tables=table_vector;
join->const_tables=const_count;
join->found_const_table_map=found_const_table_map;
+ if (join->const_tables != join->tables)
+ optimize_keyuse(join, keyuse_array);
+
+ if (optimize_semijoin_nests(join, all_table_map))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
/* Find an optimal join order of the non-constant tables. */
if (join->const_tables != join->tables)
{
- optimize_keyuse(join, keyuse_array);
if (choose_plan(join, all_table_map & ~join->const_table_map))
goto error;
}
@@ -3125,12 +3259,9 @@ typedef struct key_field_t {
*/
bool null_rejecting;
bool *cond_guard; /* See KEYUSE::cond_guard */
+ uint sj_pred_no; /* See KEYUSE::sj_pred_no */
} KEY_FIELD;
-/* Values in optimize */
-#define KEY_OPTIMIZE_EXISTS 1
-#define KEY_OPTIMIZE_REF_OR_NULL 2
-
/**
Merge new key definitions to old ones, remove those not used in both.
@@ -3294,6 +3425,52 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
}
+/*
+ Given a field, return its index in semi-join's select list, or UINT_MAX
+
+ DESCRIPTION
+ Given a field, we find its table; then see if the table is within a
+ semi-join nest and if the field was in select list of the subselect.
+ If it was, we return field's index in the select list. The value is used
+ by LooseScan strategy.
+*/
+
+static uint get_semi_join_select_list_index(Field *field)
+{
+ uint res= UINT_MAX;
+ TABLE_LIST *emb_sj_nest;
+ if ((emb_sj_nest= field->table->pos_in_table_list->embedding) &&
+ emb_sj_nest->sj_on_expr)
+ {
+ Item_in_subselect *subq_pred= emb_sj_nest->sj_subq_pred;
+ st_select_lex *subq_lex= subq_pred->unit->first_select();
+ if (subq_pred->left_expr->cols() == 1)
+ {
+ Item *sel_item= subq_lex->ref_pointer_array[0];
+ if (sel_item->type() == Item::FIELD_ITEM &&
+ ((Item_field*)sel_item)->field->eq(field))
+ {
+ res= 0;
+ }
+ }
+ else
+ {
+ for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
+ {
+ Item *sel_item= subq_lex->ref_pointer_array[i];
+ if (sel_item->type() == Item::FIELD_ITEM &&
+ ((Item_field*)sel_item)->field->eq(field))
+ {
+ res= i;
+ break;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+
/**
Add a possible key to array of possible keys if it's usable as a key
@@ -3453,11 +3630,19 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
We use null_rejecting in add_not_null_conds() to add
'othertbl.field IS NOT NULL' to tab->select_cond.
*/
- (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
- cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
- ((*value)->type() == Item::FIELD_ITEM) &&
- ((Item_field*)*value)->field->maybe_null());
+ {
+ Item *real= (*value)->real_item();
+ if (((cond->functype() == Item_func::EQ_FUNC) ||
+ (cond->functype() == Item_func::MULT_EQUAL_FUNC)) &&
+ (real->type() == Item::FIELD_ITEM) &&
+ ((Item_field*)real)->field->maybe_null())
+ (*key_fields)->null_rejecting= true;
+ else
+ (*key_fields)->null_rejecting= false;
+ }
(*key_fields)->cond_guard= NULL;
+
+ (*key_fields)->sj_pred_no= get_semi_join_select_list_index(field);
(*key_fields)++;
}
@@ -3531,8 +3716,8 @@ static bool
is_local_field (Item *field)
{
return field->real_item()->type() == Item::FIELD_ITEM
- && !(field->used_tables() & OUTER_REF_TABLE_BIT)
- && !((Item_field *)field->real_item())->depended_from;
+ && !(field->used_tables() & OUTER_REF_TABLE_BIT)
+ && !((Item_field *)field->real_item())->depended_from;
}
@@ -3793,8 +3978,10 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
keyuse.keypart_map= (key_part_map) 1 << part;
keyuse.used_tables=key_field->val->used_tables();
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
+ keyuse.ref_table_rows= 0;
keyuse.null_rejecting= key_field->null_rejecting;
keyuse.cond_guard= key_field->cond_guard;
+ keyuse.sj_pred_no= key_field->sj_pred_no;
if (insert_dynamic(keyuse_array,(uchar*) &keyuse))
return TRUE;
}
@@ -3867,6 +4054,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
keyuse.used_tables=cond_func->key_item()->used_tables();
keyuse.optimize= 0;
keyuse.keypart_map= 0;
+ keyuse.sj_pred_no= UINT_MAX;
return insert_dynamic(keyuse_array,(uchar*) &keyuse);
}
@@ -3931,20 +4119,34 @@ static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
SARGABLE_PARAM **sargables)
{
List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list);
+ List_iterator<TABLE_LIST> li2(nested_join_table->nested_join->join_list);
+ bool have_another = FALSE;
table_map tables= 0;
TABLE_LIST *table;
DBUG_ASSERT(nested_join_table->nested_join);
- while ((table= li++))
+ while ((table= li++) || (have_another && (li=li2, have_another=FALSE,
+ (table= li++))))
{
if (table->nested_join)
- add_key_fields_for_nj(join, table, end, and_level, sargables);
+ {
+ if (!table->on_expr)
+ {
+ /* It's a semi-join nest. Walk into it as if it wasn't a nest */
+ have_another= TRUE;
+ li2= li;
+ li= List_iterator<TABLE_LIST>(table->nested_join->join_list);
+ }
+ else
+ add_key_fields_for_nj(join, table, end, and_level, sargables);
+ }
else
if (!table->on_expr)
tables |= table->table->map;
}
- add_key_fields(join, end, and_level, nested_join_table->on_expr, tables,
- sargables);
+ if (nested_join_table->on_expr)
+ add_key_fields(join, end, and_level, nested_join_table->on_expr, tables,
+ sargables);
}
@@ -4128,6 +4330,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
keyuse->elements=i;
}
+ DBUG_EXECUTE("opt", print_keyuse_array(keyuse););
return FALSE;
}
@@ -4248,6 +4451,10 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
join->positions[idx].records_read=1.0; /* This is a const table */
join->positions[idx].ref_depend_map= 0;
+ join->positions[idx].loosescan_key= MAX_KEY; /* Not a LooseScan */
+ join->positions[idx].sj_strategy= SJ_OPT_NONE;
+ join->positions[idx].use_join_buffer= FALSE;
+
/* Move the const table as down as possible in best_ref */
JOIN_TAB **pos=join->best_ref+idx+1;
JOIN_TAB *next=join->best_ref[idx];
@@ -4278,23 +4485,28 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
@param thd thread for the connection that submitted the query
@param remaining_tables set of tables not included into the partial plan yet
@param idx the length of the partial plan
+ @param disable_jbuf TRUE<=> Don't use join buffering
@param record_count estimate for the number of records returned by the
partial plan
- @param read_time the cost of the partial plan
+ @param pos OUT Table access plan
+ @param loose_scan_pos OUT Table plan that uses loosescan, or set cost to
+ DBL_MAX if not possible.
@return
None
*/
-static void
+void
best_access_path(JOIN *join,
JOIN_TAB *s,
- THD *thd,
table_map remaining_tables,
uint idx,
+ bool disable_jbuf,
double record_count,
- double read_time)
+ POSITION *pos,
+ POSITION *loose_scan_pos)
{
+ THD *thd= join->thd;
KEYUSE *best_key= 0;
uint best_max_key_part= 0;
my_bool found_constraint= 0;
@@ -4304,8 +4516,13 @@ best_access_path(JOIN *join,
table_map best_ref_depends_map= 0;
double tmp;
ha_rows rec;
- DBUG_ENTER("best_access_path");
+ bool best_uses_jbuf= FALSE;
+ Loose_scan_opt loose_scan_opt;
+ DBUG_ENTER("best_access_path");
+
+ loose_scan_opt.init(join, s, remaining_tables);
+
if (s->keyuse)
{ /* Use key if possible */
TABLE *table= s->table;
@@ -4330,6 +4547,10 @@ best_access_path(JOIN *join,
/* Calculate how many key segments of the current key we can use */
start_key= keyuse;
+ loose_scan_opt.next_ref_key();
+ DBUG_PRINT("info", ("Considering ref access on key %s",
+ keyuse->table->key_info[keyuse->key].name));
+
do /* For each keypart */
{
uint keypart= keyuse->keypart;
@@ -4338,7 +4559,6 @@ best_access_path(JOIN *join,
do /* For each way to access the keypart */
{
-
/*
if 1. expression doesn't refer to forward tables
2. we won't get two ref-or-null's
@@ -4367,6 +4587,7 @@ best_access_path(JOIN *join,
if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
ref_or_null_part |= keyuse->keypart_map;
}
+ loose_scan_opt.add_keyuse(remaining_tables, keyuse);
keyuse++;
} while (keyuse->table == table && keyuse->key == key &&
keyuse->keypart == keypart);
@@ -4376,7 +4597,7 @@ best_access_path(JOIN *join,
/*
Assume that that each key matches a proportional part of table.
*/
- if (!found_part && !ft_key)
+ if (!found_part && !ft_key && !loose_scan_opt.have_a_case())
continue; // Nothing usable found
if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
@@ -4396,10 +4617,10 @@ best_access_path(JOIN *join,
}
else
{
- found_constraint= 1;
- /*
- Check if we found full key
- */
+ found_constraint= test(found_part);
+ loose_scan_opt.check_ref_access_part1(s, key, start_key, found_part);
+
+ /* Check if we found full key */
if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
!ref_or_null_part)
{ /* use eq key */
@@ -4461,7 +4682,8 @@ best_access_path(JOIN *join,
in ReuseRangeEstimateForRef-3.
*/
if (table->quick_keys.is_set(key) &&
- const_part & (1 << table->quick_key_parts[key]) &&
+ (const_part & ((1 << table->quick_key_parts[key])-1)) ==
+ (((key_part_map)1 << table->quick_key_parts[key])-1) &&
table->quick_n_ranges[key] == 1 &&
records > (double) table->quick_rows[key])
{
@@ -4472,14 +4694,11 @@ best_access_path(JOIN *join,
tmp= records;
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->covering_keys.is_set(key))
- {
- /* we can use only index tree */
- uint keys_per_block= table->file->stats.block_size/2/
- (keyinfo->key_length+table->file->ref_length)+1;
- tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
- }
+ tmp= table->file->keyread_time(key, 1, (ha_rows) tmp);
else
- tmp= record_count*min(tmp,s->worst_seeks);
+ tmp= table->file->read_time(key, 1,
+ (ha_rows) min(tmp,s->worst_seeks)-1);
+ tmp*= record_count;
}
}
else
@@ -4639,20 +4858,19 @@ best_access_path(JOIN *join,
/* Limit the number of matched rows */
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->covering_keys.is_set(key))
- {
- /* we can use only index tree */
- uint keys_per_block= table->file->stats.block_size/2/
- (keyinfo->key_length+table->file->ref_length)+1;
- tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
- }
+ tmp= table->file->keyread_time(key, 1, (ha_rows) tmp);
else
- tmp= record_count*min(tmp,s->worst_seeks);
+ tmp= table->file->read_time(key, 1,
+ (ha_rows) min(tmp,s->worst_seeks)-1);
+ tmp*= record_count;
}
else
tmp= best_time; // Do nothing
}
+ loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp);
+
} /* not ft_key */
- if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
+ if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE)
{
best_time= tmp + records/(double) TIME_FOR_COMPARE;
best= tmp;
@@ -4661,7 +4879,7 @@ best_access_path(JOIN *join,
best_max_key_part= max_key_part;
best_ref_depends_map= found_ref;
}
- }
+ } /* for each key */
records= best_records;
}
@@ -4674,7 +4892,7 @@ best_access_path(JOIN *join,
This is because table scans uses index and we would not win
anything by using a table scan.
- A word for word translation of the below if-statement in psergey's
+ A word for word translation of the below if-statement in sergefp's
understanding: we check if we should use table scan if:
(1) The found 'ref' access produces more records than a table scan
(or index scan, or quick select), or 'ref' is more expensive than
@@ -4725,6 +4943,7 @@ best_access_path(JOIN *join,
than FULL: so if RANGE is present, it's always preferred to FULL.
Here we estimate its cost.
*/
+
if (s->quick)
{
/*
@@ -4739,12 +4958,14 @@ best_access_path(JOIN *join,
tmp= record_count *
(s->quick->read_time +
(s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
+
+ loose_scan_opt.check_range_access(join, idx, s->quick);
}
else
{
/* Estimate cost of reading table. */
tmp= s->table->file->scan_time();
- if (s->table->map & join->outer_join) // Can't use join cache
+ if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache
{
/*
For each record we have to:
@@ -4790,15 +5011,21 @@ best_access_path(JOIN *join,
best_key= 0;
/* range/index_merge/ALL/index access method are "independent", so: */
best_ref_depends_map= 0;
+ best_uses_jbuf= test(!disable_jbuf && !((s->table->map &
+ join->outer_join)));
}
}
-
+
/* Update the cost information for the current partial plan */
- join->positions[idx].records_read= records;
- join->positions[idx].read_time= best;
- join->positions[idx].key= best_key;
- join->positions[idx].table= s;
- join->positions[idx].ref_depend_map= best_ref_depends_map;
+ pos->records_read= records;
+ pos->read_time= best;
+ pos->key= best_key;
+ pos->table= s;
+ pos->ref_depend_map= best_ref_depends_map;
+ pos->loosescan_key= MAX_KEY;
+ pos->use_join_buffer= best_uses_jbuf;
+
+ loose_scan_opt.save_to_position(s, loose_scan_pos);
if (!best_key &&
idx == join->const_tables &&
@@ -4833,7 +5060,7 @@ best_access_path(JOIN *join,
TRUE Fatal error
*/
-static bool
+bool
choose_plan(JOIN *join, table_map join_tables)
{
uint search_depth= join->thd->variables.optimizer_search_depth;
@@ -4842,19 +5069,34 @@ choose_plan(JOIN *join, table_map join_tables)
DBUG_ENTER("choose_plan");
join->cur_embedding_map= 0;
+ join->cur_dups_producing_tables= 0;
reset_nj_counters(join, join->join_list);
- /*
- if (SELECT_STRAIGHT_JOIN option is set)
- reorder tables so dependent tables come after tables they depend
- on, otherwise keep tables in the order they were specified in the query
- else
- Apply heuristic: pre-sort all access plans with respect to the number of
- records accessed.
- */
- my_qsort(join->best_ref + join->const_tables,
- join->tables - join->const_tables, sizeof(JOIN_TAB*),
- straight_join ? join_tab_cmp_straight : join_tab_cmp);
-
+ qsort2_cmp jtab_sort_func;
+
+ if (join->emb_sjm_nest)
+ {
+ /* We're optimizing semi-join materialization nest, so put the
+ tables from this semi-join as first
+ */
+ jtab_sort_func= join_tab_cmp_embedded_first;
+ }
+ else
+ {
+ /*
+ if (SELECT_STRAIGHT_JOIN option is set)
+ reorder tables so dependent tables come after tables they depend
+ on, otherwise keep tables in the order they were specified in the query
+ else
+ Apply heuristic: pre-sort all access plans with respect to the number of
+ records accessed.
+ */
+ jtab_sort_func= straight_join ? join_tab_cmp_straight : join_tab_cmp;
+ }
+ my_qsort2(join->best_ref + join->const_tables,
+ join->tables - join->const_tables, sizeof(JOIN_TAB*),
+ jtab_sort_func, (void*)join->emb_sjm_nest);
+ join->cur_sj_inner_tables= 0;
+
if (straight_join)
{
optimize_straight_join(join, join_tables);
@@ -4918,7 +5160,7 @@ choose_plan(JOIN *join, table_map join_tables)
*/
static int
-join_tab_cmp(const void* ptr1, const void* ptr2)
+join_tab_cmp(const void *dummy, const void* ptr1, const void* ptr2)
{
JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
@@ -4940,18 +5182,58 @@ join_tab_cmp(const void* ptr1, const void* ptr2)
*/
static int
-join_tab_cmp_straight(const void* ptr1, const void* ptr2)
+join_tab_cmp_straight(const void *dummy, const void* ptr1, const void* ptr2)
+{
+ JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
+ JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
+
+ /*
+ We don't do subquery flattening if the parent or child select has
+ STRAIGHT_JOIN modifier. It is complicated to implement and the semantics
+ is hardly useful.
+ */
+ DBUG_ASSERT(!jt1->emb_sj_nest);
+ DBUG_ASSERT(!jt2->emb_sj_nest);
+
+ if (jt1->dependent & jt2->table->map)
+ return 1;
+ if (jt2->dependent & jt1->table->map)
+ return -1;
+ return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
+}
+
+
+/*
+ Same as join_tab_cmp but tables from within the given semi-join nest go
+ first. Used when the optimizing semi-join materialization nests.
+*/
+
+static int
+join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void* ptr2)
{
+ const TABLE_LIST *emb_nest= (TABLE_LIST*) emb;
JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
+ if (jt1->emb_sj_nest == emb_nest && jt2->emb_sj_nest != emb_nest)
+ return -1;
+ if (jt1->emb_sj_nest != emb_nest && jt2->emb_sj_nest == emb_nest)
+ return 1;
+
if (jt1->dependent & jt2->table->map)
return 1;
if (jt2->dependent & jt1->table->map)
return -1;
+
+ if (jt1->found_records > jt2->found_records)
+ return 1;
+ if (jt1->found_records < jt2->found_records)
+ return -1;
+
return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
}
+
/**
Heuristic procedure to automatically guess a reasonable degree of
exhaustiveness for the greedy search procedure.
@@ -5035,15 +5317,20 @@ optimize_straight_join(JOIN *join, table_map join_tables)
uint idx= join->const_tables;
double record_count= 1.0;
double read_time= 0.0;
-
+ POSITION loose_scan_pos;
+
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
{
/* Find the best access method from 's' to the current partial plan */
- best_access_path(join, s, join->thd, join_tables, idx,
- record_count, read_time);
+ best_access_path(join, s, join_tables, idx, FALSE, record_count,
+ join->positions + idx, &loose_scan_pos);
+
/* compute the cost of the new plan extended with 's' */
record_count*= join->positions[idx].records_read;
read_time+= join->positions[idx].read_time;
+ advance_sj_state(join, join_tables, s, idx, &record_count, &read_time,
+ &loose_scan_pos);
+
join_tables&= ~(s->table->map);
++idx;
}
@@ -5152,11 +5439,17 @@ greedy_search(JOIN *join,
uint size_remain; // cardinality of remaining_tables
POSITION best_pos;
JOIN_TAB *best_table; // the next plan node to be added to the curr QEP
+ uint n_tables; // ==join->tables or # tables in the sj-mat nest we're optimizing
DBUG_ENTER("greedy_search");
/* number of tables that remain to be optimized */
- size_remain= my_count_bits(remaining_tables);
+ n_tables= size_remain= my_count_bits(remaining_tables &
+ (join->emb_sjm_nest?
+ (join->emb_sjm_nest->sj_inner_tables &
+ ~join->const_table_map)
+ :
+ ~(table_map)0));
do {
/* Find the extension of the current QEP with the lowest cost */
@@ -5176,7 +5469,7 @@ greedy_search(JOIN *join,
'join->best_positions' contains a complete optimal extension of the
current partial QEP.
*/
- DBUG_EXECUTE("opt", print_plan(join, join->tables,
+ DBUG_EXECUTE("opt", print_plan(join, n_tables,
record_count, read_time, read_time,
"optimal"););
DBUG_RETURN(FALSE);
@@ -5199,11 +5492,12 @@ greedy_search(JOIN *join,
the interleaving state to the one of the non-extended partial plan
on exit.
*/
- IF_DBUG(bool is_interleave_error= )
- check_interleaving_with_nj (best_table);
+ bool is_interleave_error __attribute__((unused))=
+ check_interleaving_with_nj(best_table);
/* This has been already checked by best_extension_by_limited_search */
DBUG_ASSERT(!is_interleave_error);
+
/* find the position of 'best_table' in 'join->best_ref' */
best_idx= idx;
JOIN_TAB *pos= join->best_ref[best_idx];
@@ -5228,6 +5522,49 @@ greedy_search(JOIN *join,
}
+/*
+ Calculate a cost of given partial join order
+
+ SYNOPSIS
+ get_partial_join_cost()
+ join IN Join to use. join->positions holds the
+ partial join order
+ idx IN # tables in the partial join order
+ read_time_arg OUT Store read time here
+ record_count_arg OUT Store record count here
+
+ DESCRIPTION
+
+ This is needed for semi-join materialization code. The idea is that
+ we detect sj-materialization after we've put all sj-inner tables into
+ the join prefix
+
+ prefix-tables semi-join-inner-tables tN
+ ^--we're here
+
+ and we'll need to get the cost of prefix-tables prefix again.
+*/
+
+void get_partial_join_cost(JOIN *join, uint n_tables, double *read_time_arg,
+ double *record_count_arg)
+{
+ double record_count= 1;
+ double read_time= 0.0;
+ for (uint i= join->const_tables; i < n_tables + join->const_tables ; i++)
+ {
+ if (join->best_positions[i].records_read)
+ {
+ record_count *= join->best_positions[i].records_read;
+ read_time += join->best_positions[i].read_time;
+ }
+ }
+ *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE;
+ *record_count_arg= record_count;
+}
+
+
+
+
/**
Find a good, possibly optimal, query execution plan (QEP) by a possibly
exhaustive search.
@@ -5374,21 +5711,33 @@ best_extension_by_limited_search(JOIN *join,
DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time,
"part_plan"););
+ table_map allowed_tables= ~(table_map)0;
+ if (join->emb_sjm_nest)
+ allowed_tables= join->emb_sjm_nest->sj_inner_tables & ~join->const_table_map;
+
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
{
table_map real_table_bit= s->table->map;
if ((remaining_tables & real_table_bit) &&
+ (allowed_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
(!idx || !check_interleaving_with_nj(s)))
{
double current_record_count, current_read_time;
+ POSITION *position= join->positions + idx;
/* Find the best access method from 's' to the current partial plan */
- best_access_path(join, s, thd, remaining_tables, idx,
- record_count, read_time);
+ POSITION loose_scan_pos;
+ best_access_path(join, s, remaining_tables, idx, FALSE, record_count,
+ join->positions + idx, &loose_scan_pos);
+
/* Compute the cost of extending the plan with 's' */
- current_record_count= record_count * join->positions[idx].records_read;
- current_read_time= read_time + join->positions[idx].read_time;
+
+ current_record_count= record_count * position->records_read;
+ current_read_time= read_time + position->read_time;
+
+ advance_sj_state(join, remaining_tables, s, idx, &current_record_count,
+ &current_read_time, &loose_scan_pos);
/* Expand only partial plans with lower cost than the best QEP so far */
if ((current_read_time +
@@ -5402,6 +5751,7 @@ best_extension_by_limited_search(JOIN *join,
(double) TIME_FOR_COMPARE),
"prune_by_cost"););
restore_prev_nj_state(s);
+ restore_prev_sj_state(remaining_tables, s, idx);
continue;
}
@@ -5414,7 +5764,7 @@ best_extension_by_limited_search(JOIN *join,
if (best_record_count > current_record_count ||
best_read_time > current_read_time ||
(idx == join->const_tables && // 's' is the first table in the QEP
- s->table == join->sort_by_table))
+ s->table == join->sort_by_table))
{
if (best_record_count >= current_record_count &&
best_read_time >= current_read_time &&
@@ -5434,11 +5784,12 @@ best_extension_by_limited_search(JOIN *join,
current_read_time,
"pruned_by_heuristic"););
restore_prev_nj_state(s);
+ restore_prev_sj_state(remaining_tables, s, idx);
continue;
}
}
- if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
+ if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) & allowed_tables )
{ /* Recursively expand the current partial plan */
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
if (best_extension_by_limited_search(join,
@@ -5475,6 +5826,7 @@ best_extension_by_limited_search(JOIN *join,
"full_plan"););
}
restore_prev_nj_state(s);
+ restore_prev_sj_state(remaining_tables, s, idx);
}
}
DBUG_RETURN(FALSE);
@@ -5528,8 +5880,9 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
(!idx|| !check_interleaving_with_nj(s)))
{
double records, best;
- best_access_path(join, s, thd, rest_tables, idx, record_count,
- read_time);
+ POSITION loose_scan_pos;
+ best_access_path(join, s, rest_tables, idx, FALSE, record_count,
+ join->positions + idx, &loose_scan_pos);
records= join->positions[idx].records_read;
best= join->positions[idx].read_time;
/*
@@ -5538,6 +5891,9 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
*/
double current_record_count=record_count*records;
double current_read_time=read_time+best;
+ advance_sj_state(join, rest_tables, s, idx, &current_record_count,
+ &current_read_time, &loose_scan_pos);
+
if (best_record_count > current_record_count ||
best_read_time > current_read_time ||
(idx == join->const_tables && s->table == join->sort_by_table))
@@ -5556,6 +5912,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
}
restore_prev_nj_state(s);
+ restore_prev_sj_state(rest_tables, s, idx);
if (join->select_options & SELECT_STRAIGHT_JOIN)
break; // Don't test all combinations
}
@@ -5568,14 +5925,15 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
Find how much space the prevous read not const tables takes in cache.
*/
-static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
+void JOIN_TAB::calc_used_field_length(bool max_fl)
{
uint null_fields,blobs,fields,rec_length;
Field **f_ptr,*field;
- MY_BITMAP *read_set= join_tab->table->read_set;
+ uint uneven_bit_fields;
+ MY_BITMAP *read_set= table->read_set;
- null_fields= blobs= fields= rec_length=0;
- for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
+ uneven_bit_fields= null_fields= blobs= fields= rec_length=0;
+ for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
if (bitmap_is_set(read_set, field->field_index))
{
@@ -5586,21 +5944,111 @@ static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
blobs++;
if (!(flags & NOT_NULL_FLAG))
null_fields++;
+ if (field->type() == MYSQL_TYPE_BIT &&
+ ((Field_bit*)field)->bit_len)
+ uneven_bit_fields++;
}
}
- if (null_fields)
- rec_length+=(join_tab->table->s->null_fields+7)/8;
- if (join_tab->table->maybe_null)
+ if (null_fields || uneven_bit_fields)
+ rec_length+=(table->s->null_fields+7)/8;
+ if (table->maybe_null)
rec_length+=sizeof(my_bool);
- if (blobs)
+ if (max_fl)
+ {
+ // TODO: to improve this estimate for max expected length
+ if (blobs)
+ {
+ uint blob_length=(uint) (table->file->stats.mean_rec_length-
+ (table->s->reclength-rec_length));
+ rec_length+=(uint) max(sizeof(void*) * blobs, blob_length);
+ }
+ max_used_fieldlength= rec_length;
+ }
+ else if (table->file->stats.mean_rec_length)
+ set_if_smaller(rec_length, table->file->stats.mean_rec_length);
+
+ /*
+ psergey-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;
+ used_null_fields= null_fields;
+ used_uneven_bit_fields= uneven_bit_fields;
+}
+
+
+/**
+ @brief
+ Check whether hash join algorithm can be used to join this table
+
+ @details
+ This function finds out whether the ref items that have been chosen
+ by the planner to access this table can be used for hash join algorithms.
+ The answer depends on a certain property of the the fields of the
+ joined tables on which the hash join key is built. If hash join is
+ allowed for all these fields the answer is positive.
+
+ @note
+ The function is supposed to be called now only after the function
+ get_best_combination has been called.
+
+ @retval TRUE it's possible to use hash join to join this table
+ @retval FALSE otherwise
+*/
+
+bool JOIN_TAB::hash_join_is_possible()
+{
+ if (type != JT_REF && type != JT_EQ_REF)
+ return FALSE;
+ KEY *keyinfo= &table->key_info[ref.key];
+ for (uint i= 0; i < ref.key_parts; i++)
{
- uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
- (join_tab->table->s->reclength- rec_length));
- rec_length+=(uint) max(4,blob_length);
+ if (!keyinfo->key_part[i].field->hash_join_is_possible())
+ return FALSE;
}
- join_tab->used_fields=fields;
- join_tab->used_fieldlength=rec_length;
- join_tab->used_blobs=blobs;
+ return TRUE;
+}
+
+
+/*
+ @brief
+ Extract pushdown conditions for a table scan
+
+ @details
+ This functions extracts pushdown conditions usable when this table is scanned.
+ The conditions are extracted either from WHERE or from ON expressions.
+ The conditions are attached to the field cache_select of this table.
+
+ @note
+ Currently the extracted conditions are used only by BNL and BNLH join.
+ algorithms.
+
+ @retval 0 on success
+ 1 otherwise
+*/
+
+int JOIN_TAB::make_scan_filter()
+{
+ COND *tmp;
+ DBUG_ENTER("make_scan_filter");
+
+ Item *cond= is_inner_table_of_outer_join() ?
+ *get_first_inner_table()->on_expr_ref : join->conds;
+
+ if (cond &&
+ (tmp=make_cond_for_table(cond, join->const_table_map | table->map,
+ table->map, FALSE, TRUE)))
+ {
+ DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
+ if (!(cache_select=
+ (SQL_SELECT*) join->thd->memdup((uchar*) select, sizeof(SQL_SELECT))))
+ DBUG_RETURN(1);
+ cache_select->cond= tmp;
+ cache_select->read_tables=join->const_table_map;
+ }
+ DBUG_RETURN(0);
}
@@ -5609,16 +6057,13 @@ cache_record_length(JOIN *join,uint idx)
{
uint length=0;
JOIN_TAB **pos,**end;
- THD *thd=join->thd;
for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
pos != end ;
pos++)
{
JOIN_TAB *join_tab= *pos;
- if (!join_tab->used_fieldlength) /* Not calced yet */
- calc_used_field_length(thd, join_tab);
- length+=join_tab->used_fieldlength;
+ length+= join_tab->get_used_fieldlength();
}
return length;
}
@@ -5709,8 +6154,24 @@ prev_record_reads(JOIN *join, uint idx, table_map found_ref)
}
-/**
- Set up join struct according to best position.
+/*
+ Set up join struct according to the picked join order in
+
+ SYNOPSIS
+ get_best_combination()
+ join The join to process (the picked join order is mainly in
+ join->best_positions)
+
+ DESCRIPTION
+ Setup join structures according the picked join order
+ - finalize semi-join strategy choices (see
+ fix_semijoin_strategies_for_picked_join_order)
+ - create join->join_tab array and put there the JOIN_TABs in the join order
+ - create data structures describing ref access methods.
+
+ RETURN
+ FALSE OK
+ TRUE Out of memory
*/
static bool
@@ -5732,6 +6193,9 @@ get_best_combination(JOIN *join)
join->full_join=0;
used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read
+
+ fix_semijoin_strategies_for_picked_join_order(join);
+
for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
{
TABLE *form;
@@ -5745,14 +6209,17 @@ get_best_combination(JOIN *join)
if (j->type == JT_CONST)
continue; // Handled in make_join_stat..
+ j->loosescan_match_tab= NULL; //non-nulls will be set later
j->ref.key = -1;
j->ref.key_parts=0;
if (j->type == JT_SYSTEM)
continue;
- if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key))
+ if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key) ||
+ (join->best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN))
{
j->type=JT_ALL;
+ j->index= join->best_positions[tablenr].loosescan_key;
if (tablenr != join->const_tables)
join->full_join=1;
}
@@ -5833,7 +6300,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
j->ref.key_err=1;
j->ref.has_record= FALSE;
j->ref.null_rejecting= 0;
- j->ref.use_count= 0;
+ j->ref.disable_cache= FALSE;
keyuse=org_keyuse;
store_key **ref_key= j->ref.key_copy;
@@ -5870,7 +6337,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
store_key_item tmp(thd, keyinfo->key_part[i].field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
- keyinfo->key_part[i].length, keyuse->val);
+ keyinfo->key_part[i].length, keyuse->val,
+ FALSE);
if (thd->is_fatal_error)
DBUG_RETURN(TRUE);
tmp.copy();
@@ -5951,7 +6419,7 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
- keyuse->val);
+ keyuse->val, FALSE);
}
/**
@@ -6029,10 +6497,13 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
row_limit= unit->select_limit_cnt;
do_send_rows= row_limit ? 1 : 0;
- join_tab->cache.buff=0; /* No caching */
+ join_tab->use_join_cache= FALSE;
+ join_tab->cache=0; /* No caching */
join_tab->table=temp_table;
+ join_tab->cache_select= 0;
join_tab->select=0;
- join_tab->select_cond=0;
+ join_tab->select_cond= 0; // Avoid valgrind warning
+ join_tab->set_select_cond(NULL, __LINE__);
join_tab->quick=0;
join_tab->type= JT_ALL; /* Map through all records */
join_tab->keys.init();
@@ -6046,6 +6517,12 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
join_tab->read_first_record= join_init_read_record;
join_tab->join= this;
join_tab->ref.key_parts= 0;
+ join_tab->keep_current_rowid= FALSE;
+ join_tab->flush_weedout_table= join_tab->check_weed_out_table= NULL;
+ join_tab->do_firstmatch= NULL;
+ join_tab->loosescan_match_tab= NULL;
+ join_tab->emb_sj_nest= NULL;
+ join_tab->pre_idx_push_select_cond= NULL;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
temp_table->status=0;
temp_table->null_row=0;
@@ -6057,6 +6534,8 @@ inline void add_cond_and_fix(Item **e1, Item *e2)
{
if (*e1)
{
+ if (!e2)
+ return;
Item *res;
if ((res= new Item_cond_and(*e1, e2)))
{
@@ -6127,9 +6606,8 @@ static void add_not_null_conds(JOIN *join)
for (uint i=join->const_tables ; i < join->tables ; i++)
{
JOIN_TAB *tab=join->join_tab+i;
- if ((tab->type == JT_REF || tab->type == JT_EQ_REF ||
- tab->type == JT_REF_OR_NULL) &&
- !tab->table->maybe_null)
+ if (tab->type == JT_REF || tab->type == JT_EQ_REF ||
+ tab->type == JT_REF_OR_NULL)
{
for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
{
@@ -6137,8 +6615,9 @@ static void add_not_null_conds(JOIN *join)
{
Item *item= tab->ref.items[keypart];
Item *notnull;
- DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
- Item_field *not_null_item= (Item_field*)item;
+ Item *real= item->real_item();
+ DBUG_ASSERT(real->type() == Item::FIELD_ITEM);
+ Item_field *not_null_item= (Item_field*)real;
JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
/*
For UPDATE queries such as:
@@ -6158,9 +6637,16 @@ static void add_not_null_conds(JOIN *join)
if (notnull->fix_fields(join->thd, &notnull))
DBUG_VOID_RETURN;
DBUG_EXECUTE("where",print_where(notnull,
- referred_tab->table->alias,
+ referred_tab->table->alias.c_ptr(),
QT_ORDINARY););
- add_cond_and_fix(&referred_tab->select_cond, notnull);
+ if (!tab->first_inner)
+ {
+ COND *new_cond= referred_tab->select_cond;
+ add_cond_and_fix(&new_cond, notnull);
+ referred_tab->set_select_cond(new_cond, __LINE__);
+ }
+ else
+ add_cond_and_fix(tab->first_inner->on_expr_ref, notnull);
}
}
}
@@ -6243,7 +6729,6 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
This function can be called only after the execution plan
has been chosen.
*/
-
static void
make_outerjoin_info(JOIN *join)
{
@@ -6270,6 +6755,9 @@ make_outerjoin_info(JOIN *join)
}
for ( ; embedding ; embedding= embedding->embedding)
{
+ /* Ignore sj-nests: */
+ if (!embedding->on_expr)
+ continue;
NESTED_JOIN *nested_join= embedding->nested_join;
if (!nested_join->counter)
{
@@ -6285,10 +6773,17 @@ make_outerjoin_info(JOIN *join)
}
if (!tab->first_inner)
tab->first_inner= nested_join->first_nested;
+ if (tab->table->reginfo.not_exists_optimize)
+ tab->first_inner->table->reginfo.not_exists_optimize= 1;
if (++nested_join->counter < nested_join->n_tables)
break;
/* Table tab is the last inner table for nested join. */
nested_join->first_nested->last_inner= tab;
+ if (tab->first_inner->table->reginfo.not_exists_optimize)
+ {
+ for (JOIN_TAB *join_tab= tab->first_inner; join_tab <= tab; join_tab++)
+ join_tab->table->reginfo.not_exists_optimize= 1;
+ }
}
}
DBUG_VOID_RETURN;
@@ -6304,6 +6799,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
add_not_null_conds(join);
table_map used_tables;
+ /*
+ Step #1: Extract constant condition
+ - Extract and check the constant part of the WHERE
+ - Extract constant parts of ON expressions from outer
+ joins and attach them appropriately.
+ */
if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */
{ /* there may be a select without a cond. */
if (join->tables > 1)
@@ -6312,11 +6813,23 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
thd->lex->current_select->master_unit() ==
&thd->lex->unit) // not upper level SELECT
join->const_table_map|=RAND_TABLE_BIT;
+
+ /*
+ Extract expressions that depend on constant tables
+ 1. Const part of the join's WHERE clause can be checked immediately
+ and if it is not satisfied then the join has empty result
+ 2. Constant parts of outer joins' ON expressions must be attached
+ there inside the triggers.
+ */
{ // Check const tables
COND *const_cond=
make_cond_for_table(cond,
join->const_table_map,
- (table_map) 0);
+ (table_map) 0, TRUE, FALSE);
+ /* Add conditions added by add_not_null_conds(). */
+ for (uint i= 0 ; i < join->const_tables ; i++)
+ add_cond_and_fix(&const_cond, join->join_tab[i].select_cond);
+
DBUG_EXECUTE("where",print_where(const_cond,"constants", QT_ORDINARY););
for (JOIN_TAB *tab= join->join_tab+join->const_tables;
tab < join->join_tab+join->tables ; tab++)
@@ -6326,18 +6839,19 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
JOIN_TAB *cond_tab= tab->first_inner;
COND *tmp= make_cond_for_table(*tab->on_expr_ref,
join->const_table_map,
- ( table_map) 0);
+ (table_map) 0, FALSE, FALSE);
if (!tmp)
continue;
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
if (!tmp)
DBUG_RETURN(1);
tmp->quick_fix_field();
- cond_tab->select_cond= !cond_tab->select_cond ? tmp :
- new Item_cond_and(cond_tab->select_cond,
- tmp);
+ COND *new_cond= !cond_tab->select_cond ? tmp :
+ new Item_cond_and(cond_tab->select_cond, tmp);
+ cond_tab->set_select_cond(new_cond, __LINE__);
if (!cond_tab->select_cond)
DBUG_RETURN(1);
+ cond_tab->select_cond->update_used_tables();
cond_tab->select_cond->quick_fix_field();
}
}
@@ -6348,20 +6862,42 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
}
}
+
+ /*
+ Step #2: Extract WHERE/ON parts
+ */
+ table_map save_used_tables= 0;
used_tables=((select->const_tables=join->const_table_map) |
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
+ JOIN_TAB *tab;
+ table_map current_map;
for (uint i=join->const_tables ; i < join->tables ; i++)
{
- JOIN_TAB *tab=join->join_tab+i;
+ tab= join->join_tab+i;
/*
first_inner is the X in queries like:
SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
*/
JOIN_TAB *first_inner_tab= tab->first_inner;
- table_map current_map= tab->table->map;
+ current_map= tab->table->map;
bool use_quick_range=0;
COND *tmp;
+ /*
+ Tables that are within SJ-Materialization nests cannot have their
+ conditions referring to preceding non-const tables.
+ - If we're looking at the first SJM table, reset used_tables
+ to refer to only allowed tables
+ */
+ if (tab->emb_sj_nest && tab->emb_sj_nest->sj_mat_info &&
+ tab->emb_sj_nest->sj_mat_info->is_used &&
+ !(used_tables & tab->emb_sj_nest->sj_inner_tables))
+ {
+ save_used_tables= used_tables;
+ used_tables= join->const_table_map | OUTER_REF_TABLE_BIT |
+ RAND_TABLE_BIT;
+ }
+
/*
Following force including random expression in last table condition.
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
@@ -6391,7 +6927,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tmp= NULL;
if (cond)
- tmp= make_cond_for_table(cond,used_tables,current_map);
+ tmp= make_cond_for_table(cond, used_tables, current_map, FALSE, FALSE);
+ /* Add conditions added by add_not_null_conds(). */
+ if (tab->select_cond)
+ add_cond_and_fix(&tmp, tab->select_cond);
if (cond && !tmp && tab->quick)
{ // Outer join
if (tab->type != JT_ALL)
@@ -6416,9 +6955,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
}
- if (tmp || !cond || tab->type == JT_REF)
+ if (tmp || !cond || tab->type == JT_REF || tab->type == JT_REF_OR_NULL ||
+ tab->type == JT_EQ_REF || first_inner_tab)
{
- DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
+ DBUG_EXECUTE("where",
+ print_where(tmp,tab->table->alias.c_ptr(),
+ QT_ORDINARY););
SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
thd->memdup((uchar*) select,
sizeof(*select)));
@@ -6438,14 +6980,15 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
DBUG_RETURN(1);
- tab->select_cond=sel->cond=tmp;
+ sel->cond= tmp;
+ tab->set_select_cond(tmp, __LINE__);
/* Push condition to storage engine if this is enabled
and the condition is not guarded */
tab->table->file->pushed_cond= NULL;
- if (thd->variables.engine_condition_pushdown)
+ if (thd->variables.engine_condition_pushdown && !first_inner_tab)
{
COND *push_cond=
- make_cond_for_table(tmp, current_map, current_map);
+ make_cond_for_table(tmp, current_map, current_map, FALSE, FALSE);
if (push_cond)
{
/* Push condition to handler */
@@ -6455,10 +6998,15 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
}
else
- tab->select_cond= sel->cond= NULL;
+ {
+ sel->cond= NULL;
+ tab->set_select_cond(NULL, __LINE__);
+ }
sel->head=tab->table;
- DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
+ DBUG_EXECUTE("where",
+ print_where(tmp,tab->table->alias.c_ptr(),
+ QT_ORDINARY););
if (tab->quick)
{
/* Use quick key read if it's a constant and it's not used
@@ -6522,7 +7070,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
(join->select_options &
OPTION_FOUND_ROWS ?
HA_POS_ERROR :
- join->unit->select_limit_cnt), 0) < 0)
+ join->unit->select_limit_cnt), 0,
+ FALSE) < 0)
{
/*
Before reporting "Impossible WHERE" for the whole query
@@ -6535,7 +7084,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
(join->select_options &
OPTION_FOUND_ROWS ?
HA_POS_ERROR :
- join->unit->select_limit_cnt),0) < 0)
+ join->unit->select_limit_cnt),0,
+ FALSE) < 0)
DBUG_RETURN(1); // Impossible WHERE
}
else
@@ -6562,21 +7112,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
2 : 1;
sel->read_tables= used_tables & ~current_map;
}
- if (i != join->const_tables && tab->use_quick != 2)
+ if (i != join->const_tables && tab->use_quick != 2 &&
+ !tab->first_inner)
{ /* Read with cache */
- if (cond &&
- (tmp=make_cond_for_table(cond,
- join->const_table_map |
- current_map,
- current_map)))
- {
- DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
- tab->cache.select=(SQL_SELECT*)
- thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
- tab->cache.select->cond=tmp;
- tab->cache.select->read_tables=join->const_table_map;
- }
- }
+ if (tab->make_scan_filter())
+ DBUG_RETURN(1);
+ }
}
}
@@ -6598,7 +7139,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(*join_tab->on_expr_ref,
join->const_table_map,
- (table_map) 0);
+ (table_map) 0, FALSE, FALSE);
if (!tmp)
continue;
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
@@ -6610,6 +7151,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (!cond_tab->select_cond)
DBUG_RETURN(1);
cond_tab->select_cond->quick_fix_field();
+ cond_tab->select_cond->update_used_tables();
+ if (cond_tab->select)
+ cond_tab->select->cond= cond_tab->select_cond;
}
}
@@ -6630,7 +7174,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
current_map= tab->table->map;
used_tables2|= current_map;
COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
- current_map);
+ current_map, FALSE, FALSE);
+ if (tab == first_inner_tab && tab->on_precond)
+ add_cond_and_fix(&tmp_cond, tab->on_precond);
if (tmp_cond)
{
JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
@@ -6667,16 +7213,126 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (!(*sel_cond_ref))
DBUG_RETURN(1);
(*sel_cond_ref)->quick_fix_field();
+ (*sel_cond_ref)->update_used_tables();
+ if (cond_tab->select)
+ cond_tab->select->cond= cond_tab->select_cond;
}
}
first_inner_tab= first_inner_tab->first_upper;
}
+
+ if (save_used_tables && !(used_tables &
+ ~(tab->emb_sj_nest->sj_inner_tables |
+ join->const_table_map | PSEUDO_TABLE_BITS)))
+ {
+ /*
+ We have reached the end of semi join nest. That is, the join order
+ looks like this:
+
+ outer_tbl1 SJ-Materialize(inner_tbl1 ... inner_tblN) outer_tbl ...
+ ^
+ \-we're here
+ At this point, we need to produce two conditions
+ - A condition that can be checked when we have all of the sj-inner
+ tables (inner_tbl1 ... inner_tblN). This will be used while doing
+ materialization.
+ - A condition that can be checked when we have all of the tables
+ in the prefix (both inner and outer).
+ */
+ tab->emb_sj_nest->sj_mat_info->join_cond=
+ cond ?
+ make_cond_after_sjm(cond, cond, save_used_tables, used_tables):
+ NULL;
+ used_tables= save_used_tables | used_tables;
+ save_used_tables= 0;
+ }
+
}
}
DBUG_RETURN(0);
}
+/*
+ Determine {after which table we'll produce ordered set}
+
+ SYNOPSIS
+ make_join_orderinfo()
+ join
+
+
+ DESCRIPTION
+ Determine if the set is already ordered for ORDER BY, so it can
+ disable join cache because it will change the ordering of the results.
+ Code handles sort table that is at any location (not only first after
+ the const tables) despite the fact that it's currently prohibited.
+ We must disable join cache if the first non-const table alone is
+ ordered. If there is a temp table the ordering is done as a last
+ operation and doesn't prevent join cache usage.
+
+ RETURN
+ Number of table after which the set will be ordered
+ join->tables if we don't need an ordered set
+*/
+
+static uint make_join_orderinfo(JOIN *join)
+{
+ JOIN_TAB *tab;
+ if (join->need_tmp)
+ return join->tables;
+ tab= join->get_sort_by_join_tab();
+ return tab ? tab-join->join_tab : join->tables;
+}
+
+/*
+ Deny usage of join buffer for the specified table
+
+ SYNOPSIS
+ set_join_cache_denial()
+ tab join table for which join buffer usage is to be denied
+
+ DESCRIPTION
+ The function denies usage of join buffer when joining the table 'tab'.
+ The table is marked as not employing any join buffer. If a join cache
+ object has been already allocated for the table this object is destroyed.
+
+ RETURN
+ none
+*/
+
+static
+void set_join_cache_denial(JOIN_TAB *join_tab)
+{
+ if (join_tab->cache)
+ {
+ /*
+ If there is a previous cache linked to this cache through the
+ next_cache pointer: remove the link.
+ */
+ if (join_tab->cache->prev_cache)
+ join_tab->cache->prev_cache->next_cache= 0;
+ /*
+ No need to do the same for next_cache since cache denial is done
+ backwards starting from the latest cache in the linked list (see
+ revise_cache_usage()).
+ */
+ DBUG_ASSERT(!join_tab->cache->next_cache);
+
+ join_tab->cache->free();
+ join_tab->cache= 0;
+ }
+ if (join_tab->use_join_cache)
+ {
+ join_tab->use_join_cache= FALSE;
+ /*
+ It could be only sub_select(). It could not be sub_seject_sjm because we
+ don't do join buffering for the first table in sjm nest.
+ */
+ join_tab[-1].next_select= sub_select;
+ }
+}
+
+
/**
The default implementation of unlock-row method of READ_RECORD,
used in all access methods.
@@ -6689,7 +7345,6 @@ void rr_unlock_row(st_join_table *tab)
}
-
/**
Pick the appropriate access method functions
@@ -6740,47 +7395,585 @@ pick_table_access_method(JOIN_TAB *tab)
}
-static void
-make_join_readinfo(JOIN *join, ulonglong options)
+/*
+ Revise usage of join buffer for the specified table and the whole nest
+
+ SYNOPSIS
+ revise_cache_usage()
+ tab join table for which join buffer usage is to be revised
+
+ DESCRIPTION
+ The function revise the decision to use a join buffer for the table 'tab'.
+ If this table happened to be among the inner tables of a nested outer join/
+ semi-join the functions denies usage of join buffers for all of them
+
+ RETURN
+ none
+*/
+
+static
+void revise_cache_usage(JOIN_TAB *join_tab)
+{
+ JOIN_TAB *tab;
+ JOIN_TAB *first_inner;
+
+ if (join_tab->first_inner)
+ {
+ JOIN_TAB *end_tab= join_tab;
+ for (first_inner= join_tab->first_inner;
+ first_inner;
+ first_inner= first_inner->first_upper)
+ {
+ for (tab= end_tab-1; tab >= first_inner; tab--)
+ set_join_cache_denial(tab);
+ end_tab= first_inner;
+ }
+ }
+ else if (join_tab->first_sj_inner_tab)
+ {
+ first_inner= join_tab->first_sj_inner_tab;
+ for (tab= join_tab-1; tab >= first_inner; tab--)
+ {
+ if (tab->first_sj_inner_tab == first_inner)
+ set_join_cache_denial(tab);
+ }
+ }
+ else set_join_cache_denial(join_tab);
+}
+
+
+/*
+ end_select-compatible function that writes the record into a sjm temptable
+
+ SYNOPSIS
+ end_sj_materialize()
+ join The join
+ join_tab Last join table
+ end_of_records FALSE <=> This call is made to pass another record
+ combination
+ TRUE <=> EOF (no action)
+
+ DESCRIPTION
+ This function is used by semi-join materialization to capture suquery's
+ resultset and write it into the temptable (that is, materialize it).
+
+ NOTE
+ This function is used only for semi-join materialization. Non-semijoin
+ materialization uses different mechanism.
+
+ RETURN
+ NESTED_LOOP_OK
+ NESTED_LOOP_ERROR
+*/
+
+static enum_nested_loop_state
+end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
+{
+ int error;
+ THD *thd= join->thd;
+ SJ_MATERIALIZATION_INFO *sjm= join_tab[-1].emb_sj_nest->sj_mat_info;
+ DBUG_ENTER("end_sj_materialize");
+ if (!end_of_records)
+ {
+ TABLE *table= sjm->table;
+
+ List_iterator<Item> it(sjm->sjm_table_cols);
+ Item *item;
+ while ((item= it++))
+ {
+ if (item->is_null())
+ DBUG_RETURN(NESTED_LOOP_OK);
+ }
+ fill_record(thd, table->field, sjm->sjm_table_cols, TRUE, FALSE);
+ if (thd->is_error())
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
+ if ((error= table->file->ha_write_row(table->record[0])))
+ {
+ /* create_myisam_from_heap will generate error if needed */
+ if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
+ create_internal_tmp_table_from_heap(thd, table,
+ sjm->sjm_table_param.start_recinfo,
+ &sjm->sjm_table_param.recinfo, error, 1))
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
+ }
+ }
+ DBUG_RETURN(NESTED_LOOP_OK);
+}
+
+
+/*
+ Check whether a join buffer can be used to join the specified table
+
+ SYNOPSIS
+ check_join_cache_usage()
+ tab joined table to check join buffer usage for
+ join join for which the check is performed
+ options options of the join
+ no_jbuf_after don't use join buffering after table with this number
+ prev_tab previous join table
+ icp_other_tables_ok OUT TRUE if condition pushdown supports
+ other tables presence
+ idx_cond_fact_out OUT TRUE if condition pushed to the index is factored
+ out of the condition pushed to the table
+
+ DESCRIPTION
+ The function finds out whether the table 'tab' can be joined using a join
+ buffer. This check is performed after the best execution plan for 'join'
+ has been chosen. If the function decides that a join buffer can be employed
+ then it selects the most appropriate join cache object that contains this
+ join buffer.
+ The result of the check and the type of the the join buffer to be used
+ depend on:
+ - the access method to access rows of the joined table
+ - whether the join table is an inner table of an outer join or semi-join
+ - whether the optimizer switches
+ outer_join_with_cache, semijoin_with_cache, join_cache_incremental,
+ join_cache_hashed, join_cache_bka,
+ are set on or off
+ - the join cache level set for the query
+ - the join 'options'.
+
+ In any case join buffer is not used if the number of the joined table is
+ greater than 'no_jbuf_after'. It's also never used if the value of
+ join_cache_level is equal to 0.
+ If the optimizer switch outer_join_with_cache is off no join buffer is
+ used for outer join operations.
+ If the optimizer switch semijoin_with_cache is off no join buffer is used
+ for semi-join operations.
+ If the optimizer switch join_cache_incremental is off no incremental join
+ buffers are used.
+ If the optimizer switch join_cache_hashed is off then the optimizer does
+ not use neither BNLH algorithm, nor BKAH algorithm to perform join
+ operations.
+
+ If the optimizer switch join_cache_bka is off then the optimizer does not
+ use neither BKA algprithm, nor BKAH algorithm to perform join operation.
+ The valid settings for join_cache_level lay in the interval 0..8.
+ If it set to 0 no join buffers are used to perform join operations.
+ Currently we differentiate between join caches of 8 levels:
+ 1 : non-incremental join cache used for BNL join algorithm
+ 2 : incremental join cache used for BNL join algorithm
+ 3 : non-incremental join cache used for BNLH join algorithm
+ 4 : incremental join cache used for BNLH join algorithm
+ 5 : non-incremental join cache used for BKA join algorithm
+ 6 : incremental join cache used for BKA join algorithm
+ 7 : non-incremental join cache used for BKAH join algorithm
+ 8 : incremental join cache used for BKAH join algorithm
+ If the value of join_cache_level is set to n then no join caches of
+ levels higher than n can be employed.
+
+ If the optimizer switches outer_join_with_cache, semijoin_with_cache,
+ join_cache_incremental, join_cache_hashed, join_cache_bka are all on
+ the following rules are applied.
+ If join_cache_level==1|2 then join buffer is used for inner joins, outer
+ joins and semi-joins with 'JT_ALL' access method. In this case a
+ JOIN_CACHE_BNL object is employed.
+ If join_cache_level==3|4 and then join buffer is used for a join operation
+ (inner join, outer join, semi-join) with 'JT_REF'/'JT_EQREF' access method
+ then a JOIN_CACHE_BNLH object is employed.
+ If an index is used to access rows of the joined table and the value of
+ join_cache_level==5|6 then a JOIN_CACHE_BKA object is employed.
+ If an index is used to access rows of the joined table and the value of
+ join_cache_level==7|8 then a JOIN_CACHE_BKAH object is employed.
+ If the value of join_cache_level is odd then creation of a non-linked
+ join cache is forced.
+
+ Currently for any join operation a join cache of the level of the
+ highest allowed and applicable level is used.
+ For example, if join_cache_level is set to 6 and the optimizer switch
+ join_cache_bka is off, while the optimizer switch join_cache_hashed is
+ on then for any inner join operation with JT_REF/JT_EQREF access method
+ to the joined table the BNLH join algorithm will be used, while for
+ the table accessed by the JT_ALL methods the BNL algorithm will be used.
+
+ If the function decides that a join buffer can be used to join the table
+ 'tab' then it sets the value of tab->use_join_buffer to TRUE and assigns
+ the selected join cache object to the field 'cache' of the previous
+ join table.
+ If the function creates a join cache object it tries to initialize it. The
+ failure to do this results in an invocation of the function that destructs
+ the created object.
+
+ NOTES
+ An inner table of a nested outer join or a nested semi-join can be currently
+ joined only when a linked cache object is employed. In these cases setting
+ join cache level to an odd number results in denial of usage of any join
+ buffer when joining the table.
+ For a nested outer join/semi-join, currently, we either use join buffers for
+ all inner tables or for none of them.
+ Some engines (e.g. Falcon) currently allow to use only a join cache
+ of the type JOIN_CACHE_BKAH when the joined table is accessed through
+ an index. For these engines setting the value of join_cache_level to 5 or 6
+ results in that no join buffer is used to join the table.
+
+ RETURN VALUE
+ cache level if cache is used, otherwise returns 0
+
+ TODO
+ Support BKA inside SJ-Materialization nests. When doing this, we'll need
+ to only store sj-inner tables in the join buffer.
+#if 0
+ JOIN_TAB *first_tab= join->join_tab+join->const_tables;
+ uint n_tables= i-join->const_tables;
+ / *
+ We normally put all preceding tables into the join buffer, except
+ for the constant tables.
+ If we're inside a semi-join materialization nest, e.g.
+
+ outer_tbl1 outer_tbl2 ( inner_tbl1, inner_tbl2 ) ...
+ ^-- we're here
+
+ then we need to put into the join buffer only the tables from
+ within the nest.
+ * /
+ if (i >= first_sjm_table && i < last_sjm_table)
+ {
+ n_tables= i - first_sjm_table; // will be >0 if we got here
+ first_tab= join->join_tab + first_sjm_table;
+ }
+#endif
+*/
+
+static
+uint check_join_cache_usage(JOIN_TAB *tab,
+ JOIN *join, ulonglong options,
+ uint no_jbuf_after,
+ JOIN_TAB *prev_tab,
+ bool *icp_other_tables_ok,
+ bool *idx_cond_fact_out)
+{
+ uint flags;
+ COST_VECT cost;
+ ha_rows rows;
+ uint bufsz= 4096;
+ JOIN_CACHE *prev_cache=0;
+ uint cache_level= join->thd->variables.join_cache_level;
+ bool force_unlinked_cache=
+ !optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL);
+ bool no_hashed_cache=
+ !optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_HASHED);
+ bool no_bka_cache=
+ !optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_BKA);
+ uint i= tab - join->join_tab;
+
+ *icp_other_tables_ok= TRUE;
+ *idx_cond_fact_out= TRUE;
+ if (cache_level == 0 || i == join->const_tables || !prev_tab)
+ return 0;
+
+ if (force_unlinked_cache && (cache_level%2 == 0))
+ cache_level--;
+
+ if (options & SELECT_NO_JOIN_CACHE)
+ goto no_join_cache;
+ /*
+ psergey-todo: why the below when execution code seems to handle the
+ "range checked for each record" case?
+ */
+ if (tab->use_quick == 2)
+ goto no_join_cache;
+
+ if (tab->is_inner_table_of_semi_join_with_first_match() &&
+ !optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE))
+ goto no_join_cache;
+ if (tab->is_inner_table_of_outer_join() &&
+ !optimizer_flag(join->thd, OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE))
+ goto no_join_cache;
+
+ /*
+ Non-linked join buffers can't guarantee one match
+ */
+ if (tab->is_nested_inner())
+ {
+ if (force_unlinked_cache || cache_level == 1)
+ goto no_join_cache;
+ if (cache_level & 1)
+ cache_level--;
+ }
+
+ /*
+ Don't use join buffering if we're dictated not to by no_jbuf_after (this
+ ...)
+ */
+ if (!(i <= no_jbuf_after) || tab->loosescan_match_tab ||
+ sj_is_materialize_strategy(join->best_positions[i].sj_strategy))
+ goto no_join_cache;
+
+ for (JOIN_TAB *first_inner= tab->first_inner; first_inner;
+ first_inner= first_inner->first_upper)
+ {
+ if (first_inner != tab && !first_inner->use_join_cache)
+ goto no_join_cache;
+ }
+ if (tab->first_sj_inner_tab && tab->first_sj_inner_tab != tab &&
+ !tab->first_sj_inner_tab->use_join_cache)
+ goto no_join_cache;
+ if (!prev_tab->use_join_cache)
+ {
+ /*
+ Check whether table tab and the previous one belong to the same nest of
+ inner tables and if so do not use join buffer when joining table tab.
+ */
+ if (tab->first_inner)
+ {
+ for (JOIN_TAB *first_inner= tab[-1].first_inner;
+ first_inner;
+ first_inner= first_inner->first_upper)
+ {
+ if (first_inner == tab->first_inner)
+ goto no_join_cache;
+ }
+ }
+ else if (tab->first_sj_inner_tab &&
+ tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab)
+ goto no_join_cache;
+ }
+
+ if (!force_unlinked_cache)
+ prev_cache= prev_tab->cache;
+
+ switch (tab->type) {
+ case JT_ALL:
+ if (cache_level == 1)
+ prev_cache= 0;
+ if ((tab->cache= new JOIN_CACHE_BNL(join, tab, prev_cache)) &&
+ ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ {
+ *icp_other_tables_ok= FALSE;
+ return (2-test(!prev_cache));
+ }
+ goto no_join_cache;
+ case JT_SYSTEM:
+ case JT_CONST:
+ case JT_REF:
+ case JT_EQ_REF:
+ if (cache_level <=2 || (no_hashed_cache && no_bka_cache))
+ goto no_join_cache;
+ flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
+ if (tab->table->covering_keys.is_set(tab->ref.key))
+ flags|= HA_MRR_INDEX_ONLY;
+ rows= tab->table->file->multi_range_read_info(tab->ref.key, 10, 20,
+ tab->ref.key_parts,
+ &bufsz, &flags, &cost);
+
+ if ((cache_level <=4 && !no_hashed_cache) || no_bka_cache ||
+ ((flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6))
+ {
+ if (!tab->hash_join_is_possible() ||
+ tab->make_scan_filter())
+ goto no_join_cache;
+ if (cache_level == 3)
+ {
+ if (prev_tab->cache)
+ goto no_join_cache;
+ prev_cache= 0;
+ }
+ if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
+ ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ {
+ *icp_other_tables_ok= FALSE;
+ return (4-test(!prev_cache));
+ }
+ goto no_join_cache;
+ }
+ if (cache_level > 4 && no_bka_cache)
+ goto no_join_cache;
+
+ if ((flags & HA_MRR_NO_ASSOCIATION) &&
+ (cache_level <= 6 || no_hashed_cache))
+ goto no_join_cache;
+
+ if ((rows != HA_POS_ERROR) && !(flags & HA_MRR_USE_DEFAULT_IMPL))
+ {
+ if (cache_level <= 6 || no_hashed_cache)
+ {
+ if (cache_level == 5)
+ prev_cache= 0;
+ if ((tab->cache= new JOIN_CACHE_BKA(join, tab, flags, prev_cache)) &&
+ ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ return (6-test(!prev_cache));
+ goto no_join_cache;
+ }
+ else
+ {
+ if (cache_level == 7)
+ prev_cache= 0;
+ if ((tab->cache= new JOIN_CACHE_BKAH(join, tab, flags, prev_cache)) &&
+ ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ {
+ *idx_cond_fact_out= FALSE;
+ return (8-test(!prev_cache));
+ }
+ goto no_join_cache;
+ }
+ }
+ goto no_join_cache;
+ default : ;
+ }
+
+no_join_cache:
+ revise_cache_usage(tab);
+ return 0;
+}
+
+
+/*
+ Plan refinement stage: do various setup things for the executor
+
+ SYNOPSIS
+ make_join_readinfo()
+ join Join being processed
+ options Join's options (checking for SELECT_DESCRIBE,
+ SELECT_NO_JOIN_CACHE)
+ no_jbuf_after Don't use join buffering after table with this number.
+
+ DESCRIPTION
+ Plan refinement stage: do various set ups for the executioner
+ - set up use of join buffering
+ - push index conditions
+ - increment relevant counters
+ - etc
+
+ RETURN
+ FALSE - OK
+ TRUE - Out of memory
+*/
+
+static bool
+make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
{
uint i;
+ uint jcl= 0;
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
- bool ordered_set= 0;
bool sorted= 1;
+ uint first_sjm_table= MAX_TABLES;
+ uint last_sjm_table= MAX_TABLES;
DBUG_ENTER("make_join_readinfo");
+
+ if (!join->select_lex->sj_nests.is_empty() &&
+ setup_semijoin_dups_elimination(join, options, no_jbuf_after))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
+ for (i= 0; i < join->const_tables; i++)
+ join->join_tab[i].partial_join_cardinality= 1;
+
for (i=join->const_tables ; i < join->tables ; i++)
{
JOIN_TAB *tab=join->join_tab+i;
TABLE *table=tab->table;
+ bool icp_other_tables_ok= FALSE;
+ bool idx_cond_fact_out= FALSE;
tab->read_record.table= table;
tab->read_record.file=table->file;
tab->read_record.unlock_row= rr_unlock_row;
tab->next_select=sub_select; /* normal select */
+ tab->sorted= sorted;
+ sorted= 0; // only first must be sorted
/*
- Determine if the set is already ordered for ORDER BY, so it can
- disable join cache because it will change the ordering of the results.
- Code handles sort table that is at any location (not only first after
- the const tables) despite the fact that it's currently prohibited.
- We must disable join cache if the first non-const table alone is
- ordered. If there is a temp table the ordering is done as a last
- operation and doesn't prevent join cache usage.
+ The approximation below for partial join cardinality is not good because
+ - it does not take into account some pushdown predicates
+ - it does not differentiate between inner joins, outer joins and semi-joins.
+ Later it should be improved.
*/
- if (!ordered_set && !join->need_tmp &&
- (table == join->sort_by_table ||
- (join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
- ordered_set= 1;
+ tab->partial_join_cardinality= join->best_positions[i].records_read *
+ (i ? (tab-1)->partial_join_cardinality : 1);
+
+ if (tab->loosescan_match_tab)
+ {
+ if (!(tab->loosescan_buf= (uchar*)join->thd->alloc(tab->
+ loosescan_key_len)))
+ return TRUE; /* purecov: inspected */
+ tab->sorted= TRUE;
+ }
- tab->sorted= sorted;
- sorted= 0; // only first must be sorted
+ /*
+ SJ-Materialization
+ */
+ if (!(i >= first_sjm_table && i < last_sjm_table))
+ tab->first_sjm_sibling= NULL;
+ if (sj_is_materialize_strategy(join->best_positions[i].sj_strategy))
+ {
+ /* This is a start of semi-join nest */
+ first_sjm_table= i;
+ last_sjm_table= i + join->best_positions[i].n_sj_tables;
+ if (i == join->const_tables)
+ join->first_select= sub_select_sjm;
+ else
+ tab[-1].next_select= sub_select_sjm;
+
+ if (setup_sj_materialization(tab))
+ return TRUE;
+ for (uint j= first_sjm_table; j != last_sjm_table; j++)
+ join->join_tab[j].first_sjm_sibling= join->join_tab + first_sjm_table;
+ }
table->status=STATUS_NO_RECORD;
pick_table_access_method (tab);
+ /*
+ This loop currently can be executed only once as the function
+ check_join_cache_usage does not change the value of tab->type.
+ It won't be true for the future code.
+ */
+ for ( ; ; )
+ {
+ enum join_type tab_type= tab->type;
+ switch (tab->type) {
+ case JT_SYSTEM:
+ case JT_CONST:
+ case JT_EQ_REF:
+ case JT_REF:
+ case JT_REF_OR_NULL:
+ case JT_ALL:
+ if ((jcl= check_join_cache_usage(tab, join, options,
+ no_jbuf_after,
+ i == last_sjm_table ?
+ join->join_tab+first_sjm_table :
+ tab-1,
+ &icp_other_tables_ok,
+ &idx_cond_fact_out)))
+ {
+ tab->use_join_cache= TRUE;
+ tab[-1].next_select=sub_select_cache;
+ }
+ break;
+ default:
+ ;
+ }
+ if (tab->type == tab_type)
+ break;
+ }
+
switch (tab->type) {
+ case JT_SYSTEM: // Only happens with left join
+ case JT_CONST: // Only happens with left join
+ /* Only happens with outer joins */
+ tab->read_first_record= tab->type == JT_SYSTEM ?
+ join_read_system :join_read_const;
+ if (table->covering_keys.is_set(tab->ref.key) &&
+ !table->no_keyread)
+ {
+ table->key_read=1;
+ table->file->extra(HA_EXTRA_KEYREAD);
+ }
+ else if (!jcl || jcl > 4)
+ push_index_cond(tab, tab->ref.key,
+ icp_other_tables_ok, idx_cond_fact_out);
+ break;
case JT_EQ_REF:
tab->read_record.unlock_row= join_read_key_unlock_row;
/* fall through */
+ if (table->covering_keys.is_set(tab->ref.key) &&
+ !table->no_keyread)
+ {
+ table->key_read=1;
+ table->file->extra(HA_EXTRA_KEYREAD);
+ }
+ else if (!jcl || jcl > 4)
+ push_index_cond(tab, tab->ref.key,
+ icp_other_tables_ok, idx_cond_fact_out);
+ break;
case JT_REF_OR_NULL:
case JT_REF:
if (tab->select)
@@ -6790,27 +7983,20 @@ make_join_readinfo(JOIN *join, ulonglong options)
}
delete tab->quick;
tab->quick=0;
- /* fall through */
- case JT_CONST: // Only happens with left join
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
table->enable_keyread();
+ else if (!jcl || jcl > 4)
+ push_index_cond(tab, tab->ref.key,
+ icp_other_tables_ok, idx_cond_fact_out);
break;
case JT_ALL:
/*
If previous table use cache
If the incoming data set is already sorted don't use cache.
+ Also don't use cache if this is the first table in semi-join
+ materialization nest.
*/
- if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
- tab->use_quick != 2 && !tab->first_inner && !ordered_set)
- {
- if ((options & SELECT_DESCRIBE) ||
- !join_init_cache(join->thd,join->join_tab+join->const_tables,
- i-join->const_tables))
- {
- tab[-1].next_select=sub_select_cache; /* Patch previous */
- }
- }
/* These init changes read_record */
if (tab->use_quick == 2)
{
@@ -6881,10 +8067,13 @@ make_join_readinfo(JOIN *join, ulonglong options)
tab->type=JT_NEXT; // Read with index_first / index_next
}
}
+ if (tab->select && tab->select->quick &&
+ tab->select->quick->index != MAX_KEY && ! tab->table->key_read)
+ push_index_cond(tab, tab->select->quick->index,
+ icp_other_tables_ok, idx_cond_fact_out);
}
break;
case JT_FT:
- case JT_SYSTEM:
break;
default:
DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
@@ -6895,7 +8084,35 @@ make_join_readinfo(JOIN *join, ulonglong options)
}
}
join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
- DBUG_VOID_RETURN;
+
+/*
+ If a join buffer is used to join a table the ordering by an index
+ for the first non-constant table cannot be employed anymore.
+ */
+ for (i=join->const_tables ; i < join->tables ; i++)
+ {
+ JOIN_TAB *tab=join->join_tab+i;
+ if (tab->use_join_cache)
+ {
+ JOIN_TAB *sort_by_tab= join->group && join->simple_group &&
+ join->group_list ?
+ join->join_tab+join->const_tables :
+ join->get_sort_by_join_tab();
+ if (sort_by_tab)
+ {
+ join->need_tmp= 1;
+ join->simple_order= join->simple_group= 0;
+ if (sort_by_tab->type == JT_NEXT)
+ {
+ sort_by_tab->type= JT_ALL;
+ sort_by_tab->read_first_record= join_init_read_record;
+ }
+ }
+ break;
+ }
+ }
+
+ DBUG_RETURN(FALSE);
}
@@ -6942,8 +8159,11 @@ void JOIN_TAB::cleanup()
select= 0;
delete quick;
quick= 0;
- x_free(cache.buff);
- cache.buff= 0;
+ if (cache)
+ {
+ cache->free();
+ cache= 0;
+ }
limit= 0;
if (table)
{
@@ -6960,6 +8180,72 @@ void JOIN_TAB::cleanup()
/**
+ Build a TABLE_REF structure for index lookup in the temporary table
+
+ @param thd Thread handle
+ @param tmp_key The temporary table key
+ @param it The iterator of items for lookup in the key
+
+ @details
+ Build TABLE_REF object for lookup in the key 'tmp_key' using items
+ accessible via item iterator 'it'.
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+bool TABLE_REF::tmp_table_index_lookup_init(THD *thd,
+ KEY *tmp_key,
+ Item_iterator &it,
+ bool value)
+{
+ uint tmp_key_parts= tmp_key->key_parts;
+ DBUG_ENTER("TABLE_REF::tmp_table_index_lookup_init");
+
+ key= 0; /* The only temp table index. */
+ key_length= tmp_key->key_length;
+ if (!(key_buff=
+ (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
+ !(key_copy=
+ (store_key**) thd->alloc((sizeof(store_key*) *
+ (tmp_key_parts + 1)))) ||
+ !(items=
+ (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
+ DBUG_RETURN(TRUE);
+
+ key_buff2= key_buff + ALIGN_SIZE(tmp_key->key_length);
+
+ KEY_PART_INFO *cur_key_part= tmp_key->key_part;
+ store_key **ref_key= key_copy;
+ uchar *cur_ref_buff= key_buff;
+
+ it.open();
+ for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
+ {
+ Item *item= it.next();
+ DBUG_ASSERT(item);
+ items[i]= item;
+ int null_count= test(cur_key_part->field->real_maybe_null());
+ *ref_key= new store_key_item(thd, cur_key_part->field,
+ /* TIMOUR:
+ the NULL byte is taken into account in
+ cur_key_part->store_length, so instead of
+ cur_ref_buff + test(maybe_null), we could
+ use that information instead.
+ */
+ cur_ref_buff + null_count,
+ null_count ? cur_ref_buff : 0,
+ cur_key_part->length, items[i], value);
+ cur_ref_buff+= cur_key_part->store_length;
+ }
+ *ref_key= NULL; /* End marker. */
+ key_err= 1;
+ key_parts= tmp_key_parts;
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
Partially cleanup JOIN after it has executed: close index or rnd read
(table cursors), free quick selects.
@@ -8176,6 +9462,7 @@ static COND *build_equal_items(THD *thd, COND *cond,
if (cond->type() == Item::COND_ITEM &&
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
cond_equal= &((Item_cond_and*) cond)->cond_equal;
+
else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
@@ -8260,6 +9547,15 @@ static int compare_fields_by_table_order(Item_field *field1,
}
+static TABLE_LIST* embedding_sjm(Item_field *item_field)
+{
+ TABLE_LIST *nest= item_field->field->table->pos_in_table_list->embedding;
+ if (nest && nest->sj_mat_info && nest->sj_mat_info->is_used)
+ return nest;
+ else
+ return NULL;
+}
+
/**
Generate minimal set of simple equalities equivalent to a multiple equality.
@@ -8293,6 +9589,23 @@ static int compare_fields_by_table_order(Item_field *field1,
So only t1.a=t3.c should be left in the lower level.
If cond is equal to 0, then not more then one equality is generated
and a pointer to it is returned as the result of the function.
+
+ Equality substutution and semi-join materialization nests:
+
+ In case join order looks like this:
+
+ outer_tbl1 outer_tbl2 SJM (inner_tbl1 inner_tbl2) outer_tbl3
+
+ We must not construct equalities like
+
+ outer_tbl1.col = inner_tbl1.col
+
+ because they would get attached to inner_tbl1 and will get evaluated
+ during materialization phase, when we don't have current value of
+ outer_tbl1.col.
+
+ Item_equal::get_first() also takes similar measures for dealing with
+ equality substitution in presense of SJM nests.
@return
- The condition with generated simple equalities or
@@ -8300,8 +9613,8 @@ static int compare_fields_by_table_order(Item_field *field1,
- 0, otherwise.
*/
-static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
- Item_equal *item_equal)
+Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
+ Item_equal *item_equal)
{
List<Item> eq_list;
Item_func_eq *eq_item= 0;
@@ -8312,18 +9625,49 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item *head;
DBUG_ASSERT(!cond || cond->type() == Item::COND_ITEM);
+ TABLE_LIST *current_sjm= NULL;
+ Item *current_sjm_head= NULL;
+
+ /*
+ Pick the "head" item: the constant one or the first in the join order
+ that's not inside some SJM nest.
+ */
if (item_const)
head= item_const;
else
{
- head= item_equal->get_first();
+ TABLE_LIST *emb_nest;
+ Item_field *item_field;
+ head= item_field= item_equal->get_first(NULL);
it++;
+ if ((emb_nest= embedding_sjm(item_field)))
+ {
+ current_sjm= emb_nest;
+ current_sjm_head= head;
+ }
}
+
Item_field *item_field;
+ /*
+ For each other item, generate "item=head" equality (except the tables that
+ are within SJ-Materialization nests, for those "head" is defined
+ differently)
+ */
while ((item_field= it++))
{
Item_equal *upper= item_field->find_item_equal(upper_levels);
Item_field *item= item_field;
+ TABLE_LIST *field_sjm= embedding_sjm(item_field);
+ if (!field_sjm)
+ {
+ current_sjm= NULL;
+ current_sjm_head= NULL;
+ }
+
+ /*
+ Check if "item_field=head" equality is already guaranteed to be true
+ on upper AND-levels.
+ */
if (upper)
{
if (item_const && upper->get_const())
@@ -8338,16 +9682,29 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
}
}
}
- if (item == item_field)
+
+ bool produce_equality= test(item == item_field);
+ if (!item_const && field_sjm && field_sjm != current_sjm)
+ {
+ /* Entering an SJM nest */
+ current_sjm_head= item_field;
+ if (!field_sjm->sj_mat_info->is_sj_scan)
+ produce_equality= FALSE;
+ }
+
+ if (produce_equality)
{
if (eq_item)
eq_list.push_back(eq_item);
- eq_item= new Item_func_eq(item_field, head);
+
+ eq_item= new Item_func_eq(item_field, current_sjm? current_sjm_head: head);
+
if (!eq_item)
return 0;
eq_item->set_cmp_func();
eq_item->quick_fix_field();
}
+ current_sjm= field_sjm;
}
if (!cond)
@@ -8377,7 +9734,6 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
return cond;
}
-
/**
Substitute every field reference in a condition by the best equal field
and eliminate all multiple equality predicates.
@@ -8630,37 +9986,6 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
}
}
-/**
- Remove additional condition inserted by IN/ALL/ANY transformation.
-
- @param conds condition for processing
-
- @return
- new conditions
-*/
-
-static Item *remove_additional_cond(Item* conds)
-{
- if (conds->name == in_additional_cond)
- return 0;
- if (conds->type() == Item::COND_ITEM)
- {
- Item_cond *cnd= (Item_cond*) conds;
- List_iterator<Item> li(*(cnd->argument_list()));
- Item *item;
- while ((item= li++))
- {
- if (item->name == in_additional_cond)
- {
- li.remove();
- if (cnd->argument_list()->elements == 1)
- return cnd->argument_list()->head();
- return conds;
- }
- }
- }
- return conds;
-}
static void
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
@@ -8722,7 +10047,6 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
}
}
-
/**
Simplify joins replacing outer joins by inner joins whenever it's
possible.
@@ -8817,13 +10141,18 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
consider any plan where one of the inner tables is before some of outer
tables.
-
+ IMPLEMENTATION
The function is implemented by a recursive procedure. On the recursive
ascent all attributes are calculated, all outer joins that can be
converted are replaced and then all unnecessary braces are removed.
As join list contains join tables in the reverse order sequential
elimination of outer joins does not require extra recursive calls.
+ SEMI-JOIN NOTES
+ Remove all semi-joins that have are within another semi-join (i.e. have
+ an "ancestor" semi-join nest)
+
+ EXAMPLES
Here is an example of a join query with invalid cross references:
@code
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
@@ -8833,14 +10162,15 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
@param join_list list representation of the join to be converted
@param conds conditions to add on expressions for converted joins
@param top true <=> conds is the where condition
-
+ @param in_sj TRUE <=> processing semi-join nest's children
@return
- The new condition, if success
- 0, otherwise
*/
static COND *
-simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
+simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
+ bool in_sj)
{
TABLE_LIST *table;
NESTED_JOIN *nested_join;
@@ -8876,7 +10206,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
the corresponding on expression is added to E.
*/
expr= simplify_joins(join, &nested_join->join_list,
- expr, FALSE);
+ expr, FALSE, in_sj || table->sj_on_expr);
if (!table->prep_on_expr || expr != table->on_expr)
{
@@ -8888,7 +10218,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
}
nested_join->used_tables= (table_map) 0;
nested_join->not_null_tables=(table_map) 0;
- conds= simplify_joins(join, &nested_join->join_list, conds, top);
+ conds= simplify_joins(join, &nested_join->join_list, conds, top,
+ in_sj || table->sj_on_expr);
used_tables= nested_join->used_tables;
not_null_tables= nested_join->not_null_tables;
/* The following two might become unequal after table elimination: */
@@ -8920,7 +10251,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
table->outer_join= 0;
if (table->on_expr)
{
- /* Add on expression to the where condition. */
+ /* Add ON expression to the WHERE or upper-level ON condition. */
if (conds)
{
conds= and_conds(conds, table->on_expr);
@@ -8989,14 +10320,25 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
prev_table= table;
}
- /* Flatten nested joins that can be flattened. */
+ /*
+ Flatten nested joins that can be flattened.
+ no ON expression and not a semi-join => can be flattened.
+ */
TABLE_LIST *right_neighbor= NULL;
li.rewind();
while ((table= li++))
{
bool fix_name_res= FALSE;
nested_join= table->nested_join;
- if (nested_join && !table->on_expr)
+ if (table->sj_on_expr && !in_sj)
+ {
+ /*
+ If this is a semi-join that is not contained within another semi-join,
+ leave it intact (otherwise it is flattened)
+ */
+ join->select_lex->sj_nests.push_back(table);
+ }
+ else if (nested_join && !table->on_expr)
{
TABLE_LIST *tbl;
List_iterator<TABLE_LIST> it(nested_join->join_list);
@@ -9025,8 +10367,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
/**
Assign each nested join structure a bit in nested_join_map.
- Assign each nested join structure (except "confluent" ones - those that
- embed only one element) a bit in nested_join_map.
+ Assign each nested join structure (except ones that embed only one element
+ and so are redundant) a bit in nested_join_map.
@param join Join being processed
@param join_list List of tables
@@ -9035,7 +10377,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
@note
This function is called after simplify_joins(), when there are no
- redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
+ redundant nested joins, #non_redundant_nested_joins <= #tables_in_join so
we will not run out of bits in nested_join_map.
@return
@@ -9064,7 +10406,9 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
*/
if (nested_join->n_tables != 1)
{
- nested_join->nj_map= (nested_join_map) 1 << first_unused++;
+ /* Don't assign bits to sj-nests */
+ if (table->on_expr)
+ nested_join->nj_map= (nested_join_map) 1 << first_unused++;
first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
first_unused);
}
@@ -9093,14 +10437,16 @@ static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
while ((table= li++))
{
NESTED_JOIN *nested_join;
+ bool is_eliminated_nest= FALSE;
if ((nested_join= table->nested_join))
{
nested_join->counter= 0;
- //nested_join->n_tables= my_count_bits(nested_join->used_tables &
- // ~join->eliminated_tables);
nested_join->n_tables= reset_nj_counters(join, &nested_join->join_list);
+ if (!nested_join->n_tables)
+ is_eliminated_nest= TRUE;
}
- if (!table->table || (table->table->map & ~join->eliminated_tables))
+ if ((!table->table && !is_eliminated_nest) ||
+ (table->table && (table->table->map & ~join->eliminated_tables)))
n++;
}
DBUG_RETURN(n);
@@ -9215,28 +10561,31 @@ static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
Do update counters for "pairs of brackets" that we've left (marked as
X,Y,Z in the above picture)
*/
- for (;next_emb; next_emb= next_emb->embedding)
+ for (;next_emb && next_emb != join->emb_sjm_nest; next_emb= next_emb->embedding)
{
- next_emb->nested_join->counter++;
- if (next_emb->nested_join->counter == 1)
+ if (!next_emb->sj_on_expr)
{
- /*
- next_emb is the first table inside a nested join we've "entered". In
- the picture above, we're looking at the 'X' bracket. Don't exit yet as
- X bracket might have Y pair bracket.
+ next_emb->nested_join->counter++;
+ if (next_emb->nested_join->counter == 1)
+ {
+ /*
+ next_emb is the first table inside a nested join we've "entered". In
+ the picture above, we're looking at the 'X' bracket. Don't exit yet as
+ X bracket might have Y pair bracket.
+ */
+ join->cur_embedding_map |= next_emb->nested_join->nj_map;
+ }
+
+ if (next_emb->nested_join->n_tables !=
+ next_emb->nested_join->counter)
+ break;
+
+ /*
+ We're currently at Y or Z-bracket as depicted in the above picture.
+ Mark that we've left it and continue walking up the brackets hierarchy.
*/
- join->cur_embedding_map |= next_emb->nested_join->nj_map;
+ join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
}
-
- if (next_emb->nested_join->n_tables !=
- next_emb->nested_join->counter)
- break;
-
- /*
- We're currently at Y or Z-bracket as depicted in the above picture.
- Mark that we've left it and continue walking up the brackets hierarchy.
- */
- join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
}
return FALSE;
}
@@ -9298,27 +10647,113 @@ static void restore_prev_nj_state(JOIN_TAB *last)
{
TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
JOIN *join= last->join;
- for (;last_emb != NULL; last_emb= last_emb->embedding)
+ for (;last_emb != NULL && last_emb != join->emb_sjm_nest;
+ last_emb= last_emb->embedding)
{
- NESTED_JOIN *nest= last_emb->nested_join;
- DBUG_ASSERT(nest->counter > 0);
-
- bool was_fully_covered= nest->is_fully_covered();
-
- if (--nest->counter == 0)
- join->cur_embedding_map&= ~nest->nj_map;
-
- if (!was_fully_covered)
- break;
+ if (!last_emb->sj_on_expr)
+ {
+ NESTED_JOIN *nest= last_emb->nested_join;
+ DBUG_ASSERT(nest->counter > 0);
+
+ bool was_fully_covered= nest->is_fully_covered();
+
+ if (--nest->counter == 0)
+ join->cur_embedding_map&= ~nest->nj_map;
+
+ if (!was_fully_covered)
+ break;
+
+ join->cur_embedding_map|= nest->nj_map;
+ }
+ }
+}
+
+
+
+/*
+ Change access methods not to use join buffering and adjust costs accordingly
+
+ SYNOPSIS
+ optimize_wo_join_buffering()
+ join
+ first_tab The first tab to do re-optimization for
+ last_tab The last tab to do re-optimization for
+ last_remaining_tables Bitmap of tables that are not in the
+ [0...last_tab] join prefix
+ first_alt TRUE <=> Use the LooseScan plan for the first_tab
+ no_jbuf_before Don't allow to use join buffering before this
+ table
+ reopt_rec_count OUT New output record count
+ reopt_cost OUT New join prefix cost
+
+ DESCRIPTION
+ Given a join prefix [0; ... first_tab], change the access to the tables
+ in the [first_tab; last_tab] not to use join buffering. This is needed
+ because some semi-join strategies cannot be used together with the join
+ buffering.
+ In general case the best table order in [first_tab; last_tab] range with
+ join buffering is different from the best order without join buffering but
+ we don't try finding a better join order. (TODO ask Igor why did we
+ chose not to do this in the end. that's actually the difference from the
+ forking approach)
+*/
+
+void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
+ table_map last_remaining_tables,
+ bool first_alt, uint no_jbuf_before,
+ double *outer_rec_count, double *reopt_cost)
+{
+ double cost, rec_count;
+ table_map reopt_remaining_tables= last_remaining_tables;
+ uint i;
+
+ if (first_tab > join->const_tables)
+ {
+ cost= join->positions[first_tab - 1].prefix_cost.total_cost();
+ rec_count= join->positions[first_tab - 1].prefix_record_count;
+ }
+ else
+ {
+ cost= 0.0;
+ rec_count= 1;
+ }
+
+ *outer_rec_count= rec_count;
+ for (i= first_tab; i <= last_tab; i++)
+ reopt_remaining_tables |= join->positions[i].table->table->map;
+
+ for (i= first_tab; i <= last_tab; i++)
+ {
+ JOIN_TAB *rs= join->positions[i].table;
+ POSITION pos, loose_scan_pos;
- join->cur_embedding_map|= nest->nj_map;
+ if ((i == first_tab && first_alt) || join->positions[i].use_join_buffer)
+ {
+ /* Find the best access method that would not use join buffering */
+ best_access_path(join, rs, reopt_remaining_tables, i,
+ TRUE, rec_count,
+ &pos, &loose_scan_pos);
+ }
+ else
+ pos= join->positions[i];
+
+ if ((i == first_tab && first_alt))
+ pos= loose_scan_pos;
+
+ reopt_remaining_tables &= ~rs->table->map;
+ rec_count *= pos.records_read;
+ cost += pos.read_time;
+
+ if (!rs->emb_sj_nest)
+ *outer_rec_count *= pos.records_read;
}
+ *reopt_cost= cost;
}
static COND *
optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
- Item::cond_result *cond_value)
+ Item::cond_result *cond_value, COND_EQUAL **cond_equal)
{
THD *thd= join->thd;
DBUG_ENTER("optimize_cond");
@@ -9326,7 +10761,7 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
if (!conds)
{
*cond_value= Item::COND_TRUE;
- build_equal_items(join->thd, NULL, NULL, join_list, &join->cond_equal);
+ build_equal_items(join->thd, NULL, NULL, join_list, cond_equal);
}
else
{
@@ -9500,7 +10935,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
return (COND*) 0;
}
}
- else if (cond->const_item())
+ else if (cond->const_item() && !cond->is_expensive())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
@@ -9960,6 +11395,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item::REF_ITEM:
case Item::NULL_ITEM:
case Item::VARBIN_ITEM:
+ case Item::CACHE_ITEM:
+ case Item::EXPR_CACHE_ITEM:
if (make_copy_field)
{
DBUG_ASSERT(((Item_result_field*)item)->result_field);
@@ -10031,11 +11468,6 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
be used for name resolving; can be "".
*/
-#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
-#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
-#define RATIO_TO_PACK_ROWS 2
-#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
-
TABLE *
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
@@ -10108,6 +11540,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
group=0; // Can't use group key
else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
{
+ /*
+ marker == 4 means two things:
+ - store NULLs in the key, and
+ - convert BIT fields to 64-bit long, needed because MEMORY tables
+ can't index BIT fields.
+ */
(*tmp->item)->marker=4; // Store null in key
if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
using_unique_constraint=1;
@@ -10178,7 +11616,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
thd->mem_root= &table->mem_root;
table->field=reg_field;
- table->alias= table_alias;
+ table->alias.set(table_alias, strlen(table_alias), table_alias_charset);
+
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
table->map=1;
@@ -10219,6 +11658,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (item->used_tables() & OUTER_REF_TABLE_BIT)
item->update_used_tables();
if (type == Item::SUBSELECT_ITEM ||
+ (item->get_cached_item() &&
+ item->get_cached_item()->type() == Item::SUBSELECT_ITEM ) ||
(item->used_tables() & ~OUTER_REF_TABLE_BIT))
{
/*
@@ -10304,7 +11745,15 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
group != 0,
!force_copy_fields &&
(not_all_columns || group !=0),
- item->marker == 4, force_copy_fields,
+ /*
+ If item->marker == 4 then we force create_tmp_field
+ to create a 64-bit longs for BIT fields because HEAP
+ tables can't index BIT fields directly. We do the same
+ for distinct, as we want the distinct index to be
+ usable in this case too.
+ */
+ item->marker == 4 || param->bit_fields_as_long, // psergey-feb17
+ force_copy_fields,
param->convert_blob_length);
if (!new_field)
@@ -10544,7 +11993,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
null_count=(null_count+7) & ~7; // move to next byte
// fix table name in field entry
- field->table_name= &table->alias;
+ field->set_table_name(&table->alias);
}
param->copy_field_end=copy;
@@ -10576,7 +12025,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
param->group_buff=group_buff;
share->keys=1;
share->uniques= test(using_unique_constraint);
- table->key_info=keyinfo;
+ table->key_info= table->s->key_info= keyinfo;
keyinfo->key_part=key_part_info;
keyinfo->flags=HA_NOSAME;
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
@@ -10642,29 +12091,40 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*/
DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
- null_pack_length-=hidden_null_pack_length;
- keyinfo->key_parts= ((field_count-param->hidden_field_count)+
- test(null_pack_length));
- table->distinct= 1;
- share->keys= 1;
if (blob_count)
{
- using_unique_constraint=1;
+ /*
+ Special mode for index creation in MyISAM used to support unique
+ indexes on blobs with arbitrary length. Such indexes cannot be
+ used for lookups.
+ */
+ //// psergey-merge: using_unique_constraint=1;
share->uniques= 1;
}
+ null_pack_length-=hidden_null_pack_length;
+ keyinfo->key_parts= ((field_count-param->hidden_field_count)+
+ (share->uniques ? test(null_pack_length) : 0));
+ table->distinct= 1;
+ share->keys= 1;
if (!(key_part_info= (KEY_PART_INFO*)
alloc_root(&table->mem_root,
keyinfo->key_parts * sizeof(KEY_PART_INFO))))
goto err;
bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
- table->key_info=keyinfo;
+ table->key_info= table->s->key_info= keyinfo;
keyinfo->key_part=key_part_info;
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
- keyinfo->key_length=(uint16) reclength;
+ keyinfo->key_length= 0; // Will compute the sum of the parts below.
keyinfo->name= (char*) "distinct_key";
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
keyinfo->rec_per_key=0;
- if (null_pack_length)
+
+ /*
+ Create an extra field to hold NULL bits so that unique indexes on
+ blobs can distinguish NULL from 0. This extra field is not needed
+ when we do not use UNIQUE indexes for blobs.
+ */
+ if (null_pack_length && share->uniques)
{
key_part_info->null_bit=0;
key_part_info->offset=hidden_null_pack_length;
@@ -10691,6 +12151,24 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->field= *reg_field;
key_part_info->offset= (*reg_field)->offset(table->record[0]);
key_part_info->length= (uint16) (*reg_field)->pack_length();
+ /* 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.
+ This should be factored out, e.g. as a method of Field.
+ In addition it is not clear if any of the Field::*_length
+ methods is supposed to compute the same length. If so, it
+ might be reused.
+ */
+ key_part_info->store_length= key_part_info->length;
+
+ if ((*reg_field)->real_maybe_null())
+ key_part_info->store_length+= HA_KEY_NULL_LENGTH;
+ if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
+ (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
+ key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
+
+ keyinfo->key_length+= key_part_info->store_length;
+
key_part_info->type= (uint8) (*reg_field)->key_type();
key_part_info->key_type =
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
@@ -10705,10 +12183,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
share->db_record_offset= 1;
if (share->db_type() == TMP_ENGINE_HTON)
{
- if (create_internal_tmp_table(table,param,select_options))
+ if (create_internal_tmp_table(table, param->keyinfo, param->start_recinfo,
+ &param->recinfo, select_options))
goto err;
}
- if (open_tmp_table(table))
+ DBUG_PRINT("info", ("skip_create_table: %d", (int)param->skip_create_table));
+ if (!param->skip_create_table && open_tmp_table(table))
goto err;
thd->mem_root= mem_root_save;
@@ -10724,6 +12204,7 @@ err:
}
+
/****************************************************************************/
/**
@@ -10852,7 +12333,7 @@ error:
}
-static bool open_tmp_table(TABLE *table)
+bool open_tmp_table(TABLE *table)
{
int error;
if ((error= table->file->ha_open(table, table->s->table_name.str, O_RDWR,
@@ -10870,15 +12351,45 @@ static bool open_tmp_table(TABLE *table)
#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
-/* Create internal Aria temporary table */
+/*
+ Create internal (MyISAM or Maria) temporary table
+
+ SYNOPSIS
+ create_internal_tmp_table()
+ table Table object that descrimes the table to be created
+ keyinfo Description of the index (there is always one index)
+ start_recinfo engine's column descriptions
+ recinfo INOUT End of engine's column descriptions
+ options Option bits
+
+ DESCRIPTION
+ Create an internal emporary table according to passed description. The is
+ assumed to have one unique index or constraint.
+
+ The passed array or ENGINE_COLUMNDEF structures must have this form:
+
+ 1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
+ when there are many nullable columns)
+ 2. Table columns
+ 3. One free ENGINE_COLUMNDEF element (*recinfo points here)
+
+ This function may use the free element to create hash column for unique
+ constraint.
+
+ RETURN
+ FALSE - OK
+ TRUE - Error
+*/
+
-static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options)
+bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
+ ulonglong options)
{
int error;
MARIA_KEYDEF keydef;
MARIA_UNIQUEDEF uniquedef;
- KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
MARIA_CREATE_INFO create_info;
DBUG_ENTER("create_internal_tmp_table");
@@ -10906,10 +12417,10 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
uniquedef.null_are_equal=1;
/* Create extra column for hash value */
- bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
- param->recinfo->type= FIELD_CHECK;
- param->recinfo->length= MARIA_UNIQUE_HASH_LENGTH;
- param->recinfo++;
+ bzero((uchar*) *recinfo,sizeof(**recinfo));
+ (*recinfo)->type= FIELD_CHECK;
+ (*recinfo)->length= MARIA_UNIQUE_HASH_LENGTH;
+ (*recinfo)++;
share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
}
else
@@ -10969,8 +12480,8 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
!share->blob_fields ? STATIC_RECORD :
BLOCK_RECORD,
share->keys, &keydef,
- (uint) (param->recinfo-param->start_recinfo),
- param->start_recinfo,
+ (uint) (*recinfo-start_recinfo),
+ start_recinfo,
share->uniques, &uniquedef,
&create_info,
HA_CREATE_TMP_TABLE)))
@@ -10989,11 +12500,13 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
- TMP_TABLE_PARAM *param,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
int error,
bool ignore_last_dupp_key_error)
{
- return create_internal_tmp_table_from_heap2(thd, table, param, error,
+ return create_internal_tmp_table_from_heap2(thd, table,
+ start_recinfo, recinfo, error,
ignore_last_dupp_key_error,
maria_hton,
"converting HEAP to Aria");
@@ -11001,15 +12514,46 @@ bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
#else
+/*
+ Create internal (MyISAM or Maria) temporary table
+
+ SYNOPSIS
+ create_internal_tmp_table()
+ table Table object that descrimes the table to be created
+ keyinfo Description of the index (there is always one index)
+ start_recinfo engine's column descriptions
+ recinfo INOUT End of engine's column descriptions
+ options Option bits
+
+ DESCRIPTION
+ Create an internal emporary table according to passed description. The is
+ assumed to have one unique index or constraint.
+
+ The passed array or ENGINE_COLUMNDEF structures must have this form:
+
+ 1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
+ when there are many nullable columns)
+ 2. Table columns
+ 3. One free ENGINE_COLUMNDEF element (*recinfo points here)
+
+ This function may use the free element to create hash column for unique
+ constraint.
+
+ RETURN
+ FALSE - OK
+ TRUE - Error
+*/
+
/* Create internal MyISAM temporary table */
-static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options)
+bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
+ ulonglong options)
{
int error;
MI_KEYDEF keydef;
MI_UNIQUEDEF uniquedef;
- KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
DBUG_ENTER("create_internal_tmp_table");
@@ -11036,10 +12580,10 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
uniquedef.null_are_equal=1;
/* Create extra column for hash value */
- bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
- param->recinfo->type= FIELD_CHECK;
- param->recinfo->length=MI_UNIQUE_HASH_LENGTH;
- param->recinfo++;
+ bzero((uchar*) *recinfo,sizeof(**recinfo));
+ (*recinfo)->type= FIELD_CHECK;
+ (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
+ (*recinfo)++;
share->reclength+=MI_UNIQUE_HASH_LENGTH;
}
else
@@ -11096,8 +12640,8 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
create_info.data_file_length= ~(ulonglong) 0;
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
- (uint) (param->recinfo-param->start_recinfo),
- param->start_recinfo,
+ (uint) (*recinfo-start_recinfo),
+ start_recinfo,
share->uniques, &uniquedef,
&create_info,
HA_CREATE_TMP_TABLE)))
@@ -11119,11 +12663,13 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
*/
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
- TMP_TABLE_PARAM *param,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
int error,
bool ignore_last_dupp_key_error)
{
- return create_internal_tmp_table_from_heap2(thd, table, param, error,
+ return create_internal_tmp_table_from_heap2(thd, table,
+ start_recinfo, recinfo, error,
ignore_last_dupp_key_error,
myisam_hton,
"converting HEAP to MyISAM");
@@ -11140,7 +12686,8 @@ bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
static bool
create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
- TMP_TABLE_PARAM *param,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
int error,
bool ignore_last_dupp_key_error,
handlerton *hton,
@@ -11174,8 +12721,9 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
save_proc_info=thd->proc_info;
thd_proc_info(thd, proc_info);
- if (create_internal_tmp_table(&new_table, param,
- thd->lex->select_lex.options | thd->options))
+ if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo,
+ recinfo, thd->lex->select_lex.options |
+ thd->options))
goto err2;
if (open_tmp_table(&new_table))
goto err1;
@@ -11268,7 +12816,7 @@ free_tmp_table(THD *thd, TABLE *entry)
MEM_ROOT own_root= entry->mem_root;
const char *save_proc_info;
DBUG_ENTER("free_tmp_table");
- DBUG_PRINT("enter",("table: %s",entry->alias));
+ DBUG_PRINT("enter",("table: %s",entry->alias.c_ptr()));
save_proc_info=thd->proc_info;
thd_proc_info(thd, "removing tmp table");
@@ -11388,7 +12936,6 @@ Next_select_func setup_end_select_func(JOIN *join)
@retval
-1 if error should be sent
*/
-
static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
@@ -11449,17 +12996,20 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
else if (join->send_row_on_empty_set())
{
- List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
- fields);
- rc= join->result->send_data(*columns_list);
+ if (!join->having || join->having->val_int())
+ {
+ List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
+ fields);
+ rc= join->result->send_data(*columns_list);
+ }
}
}
else
{
DBUG_ASSERT(join->tables);
- error= sub_select(join,join_tab,0);
+ error= join->first_select(join,join_tab,0);
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
- error= sub_select(join,join_tab,1);
+ error= join->first_select(join,join_tab,1);
if (error == NESTED_LOOP_QUERY_LIMIT)
error= NESTED_LOOP_OK; /* select_limit used */
}
@@ -11512,33 +13062,226 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
+int rr_sequential_and_unpack(READ_RECORD *info)
+{
+ int error;
+ if ((error= rr_sequential(info)))
+ return error;
+
+ for (Copy_field *cp= info->copy_field; cp != info->copy_field_end; cp++)
+ (*cp->do_copy)(cp);
+
+ return error;
+}
+
+
+/*
+ Semi-join materialization join function
+
+ SYNOPSIS
+ sub_select_sjm()
+ join The join
+ join_tab The first table in the materialization nest
+ end_of_records FALSE <=> This call is made to pass another record
+ combination
+ TRUE <=> EOF
+
+ DESCRIPTION
+ This is a join execution function that does materialization of a join
+ suborder before joining it to the rest of the join.
+
+ The table pointed by join_tab is the first of the materialized tables.
+ This function first creates the materialized table and then switches to
+ joining the materialized table with the rest of the join.
+
+ The materialized table can be accessed in two ways:
+ - index lookups
+ - full table scan
+
+ RETURN
+ One of enum_nested_loop_state values
+*/
+
enum_nested_loop_state
-sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
+sub_select_sjm(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
{
+ int res;
enum_nested_loop_state rc;
+ DBUG_ENTER("sub_select_sjm");
+
+ if (!join_tab->emb_sj_nest)
+ {
+ /*
+ We're handling GROUP BY/ORDER BY, this is the first table, and we've
+ actually executed the join already and now we're just reading the
+ result of the join from the temporary table.
+ Bypass to regular join handling.
+ Yes, it would be nicer if sub_select_sjm wasn't called at all in this
+ case but there's no easy way to arrange this.
+ */
+ rc= sub_select(join, join_tab, end_of_records);
+ DBUG_RETURN(rc);
+ }
+
+ SJ_MATERIALIZATION_INFO *sjm= join_tab->emb_sj_nest->sj_mat_info;
+ if (end_of_records)
+ {
+ rc= (*join_tab[sjm->tables - 1].next_select)(join,
+ join_tab + sjm->tables,
+ end_of_records);
+ DBUG_RETURN(rc);
+ }
+ if (!sjm->materialized)
+ {
+ /*
+ Do the materialization. First, put end_sj_materialize after the last
+ inner table so we can catch record combinations of sj-inner tables.
+ */
+ Next_select_func next_func= join_tab[sjm->tables - 1].next_select;
+ join_tab[sjm->tables - 1].next_select= end_sj_materialize;
+
+ /*
+ Now run the join for the inner tables. The first call is to run the
+ join, the second one is to signal EOF (this is essential for some
+ join strategies, e.g. it will make join buffering flush the records)
+ */
+ if ((rc= sub_select(join, join_tab, FALSE)) < 0 ||
+ (rc= sub_select(join, join_tab, TRUE/*EOF*/)) < 0)
+ {
+ join_tab[sjm->tables - 1].next_select= next_func;
+ DBUG_RETURN(rc); /* it's NESTED_LOOP_(ERROR|KILLED)*/
+ }
+ join_tab[sjm->tables - 1].next_select= next_func;
+
+ /*
+ Ok, materialization finished. Initialize the access to the temptable
+ */
+ sjm->materialized= TRUE;
+ join_tab->read_record.read_record= join_no_more_records;
+ if (sjm->is_sj_scan)
+ {
+ /* Initialize full scan */
+ JOIN_TAB *last_tab= join_tab + (sjm->tables - 1);
+ init_read_record(&last_tab->read_record, join->thd,
+ sjm->table, NULL, TRUE, TRUE, FALSE);
+
+ DBUG_ASSERT(last_tab->read_record.read_record == rr_sequential);
+ last_tab->read_first_record= join_read_record_no_init;
+ last_tab->read_record.copy_field= sjm->copy_field;
+ last_tab->read_record.copy_field_end= sjm->copy_field +
+ sjm->sjm_table_cols.elements;
+ last_tab->read_record.read_record= rr_sequential_and_unpack;
+ }
+ }
+
+ if (sjm->is_sj_scan)
+ {
+ /* Do full scan of the materialized table */
+ JOIN_TAB *last_tab= join_tab + (sjm->tables - 1);
+
+ Item *save_cond= last_tab->select_cond;
+ last_tab->set_select_cond(sjm->join_cond, __LINE__);
+
+ rc= sub_select(join, last_tab, end_of_records);
+ last_tab->set_select_cond(save_cond, __LINE__);
+ DBUG_RETURN(rc);
+ }
+ else
+ {
+ /* Do index lookup in the materialized table */
+ if ((res= join_read_key2(join_tab->join->thd, join_tab,
+ sjm->table, sjm->tab_ref)) == 1)
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
+ if (res || !sjm->in_equality->val_int())
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ }
+ rc= (*join_tab[sjm->tables - 1].next_select)(join,
+ join_tab + sjm->tables,
+ end_of_records);
+ DBUG_RETURN(rc);
+}
+
+
+/*
+ Fill the join buffer with partial records, retrieve all full matches for them
+
+ SYNOPSIS
+ sub_select_cache()
+ join pointer to the structure providing all context info for the query
+ join_tab the first next table of the execution plan to be retrieved
+ end_records true when we need to perform final steps of the retrieval
+
+ DESCRIPTION
+ For a given table Ti= join_tab from the sequence of tables of the chosen
+ execution plan T1,...,Ti,...,Tn the function just put the partial record
+ t1,...,t[i-1] into the join buffer associated with table Ti unless this
+ is the last record added into the buffer. In this case, the function
+ additionally finds all matching full records for all partial
+ records accumulated in the buffer, after which it cleans the buffer up.
+ If a partial join record t1,...,ti is extended utilizing a dynamic
+ range scan then it is not put into the join buffer. Rather all matching
+ records are found for it at once by the function sub_select.
+
+ NOTES
+ The function implements the algorithmic schema for both Blocked Nested
+ Loop Join and Batched Key Access Join. The difference can be seen only at
+ the level of of the implementation of the put_record and join_records
+ virtual methods for the cache object associated with the join_tab.
+ The put_record method accumulates records in the cache, while the
+ join_records method builds all matching join records and send them into
+ the output stream.
+
+ RETURN
+ return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
+*/
+
+enum_nested_loop_state
+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 */
+ DBUG_ASSERT(cache != NULL);
+
+ join_tab->cache->reset_join(join);
+
if (end_of_records)
{
- rc= flush_cached_records(join,join_tab,FALSE);
+ rc= cache->join_records(FALSE);
if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
- rc= sub_select(join,join_tab,end_of_records);
- return rc;
+ rc= sub_select(join, join_tab, end_of_records);
+ DBUG_RETURN(rc);
}
- if (join->thd->killed) // If aborted by user
+ if (join->thd->killed)
{
+ /* The user has aborted the execution of the query */
join->thd->send_kill_message();
- return NESTED_LOOP_KILLED; /* purecov: inspected */
+ DBUG_RETURN(NESTED_LOOP_KILLED);
}
- if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
+ if (!test_if_use_dynamic_range_scan(join_tab))
{
- if (!store_record_in_cache(&join_tab->cache))
- return NESTED_LOOP_OK; // There is more room in cache
- return flush_cached_records(join,join_tab,FALSE);
+ if (!cache->put_record())
+ DBUG_RETURN(NESTED_LOOP_OK);
+ /*
+ We has decided that after the record we've just put into the buffer
+ won't add any more records. Now try to find all the matching
+ extensions for all records in the buffer.
+ */
+ rc= cache->join_records(FALSE);
+ DBUG_RETURN(rc);
}
- rc= flush_cached_records(join, join_tab, TRUE);
+ /*
+ TODO: Check whether we really need the call below and we can't do
+ without it. If it's not the case remove it.
+ */
+ rc= cache->join_records(TRUE);
if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
rc= sub_select(join, join_tab, end_of_records);
- return rc;
+ DBUG_RETURN(rc);
}
/**
@@ -11664,14 +13407,24 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
enum_nested_loop_state
sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
+ DBUG_ENTER("sub_select");
+
join_tab->table->null_row=0;
if (end_of_records)
- return (*join_tab->next_select)(join,join_tab+1,end_of_records);
-
+ {
+ enum_nested_loop_state nls=
+ (*join_tab->next_select)(join,join_tab+1,end_of_records);
+ DBUG_RETURN(nls);
+ }
int error;
enum_nested_loop_state rc= NESTED_LOOP_OK;
READ_RECORD *info= &join_tab->read_record;
+ if (join_tab->flush_weedout_table)
+ {
+ do_sj_reset(join_tab->flush_weedout_table);
+ }
+
if (join->resume_nested_loop)
{
/* If not the last table, plunge down the nested loop */
@@ -11699,19 +13452,57 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
join_tab->last_inner->first_unmatched= join_tab;
if (join_tab->on_precond && !join_tab->on_precond->val_int())
rc= NESTED_LOOP_NO_MORE_ROWS;
- }
+ }
join->thd->row_count= 0;
+
+ if (join_tab->loosescan_match_tab)
+ join_tab->loosescan_match_tab->found_match= FALSE;
if (rc != NESTED_LOOP_NO_MORE_ROWS)
{
error= (*join_tab->read_first_record)(join_tab);
+ if (join_tab->keep_current_rowid)
+ join_tab->table->file->position(join_tab->table->record[0]);
rc= evaluate_join_record(join, join_tab, error);
}
}
-
- while (rc == NESTED_LOOP_OK)
+
+ /*
+ Note: psergey has added the 2nd part of the following condition; the
+ change should probably be made in 5.1, too.
+ */
+ bool skip_over= FALSE;
+ while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab)
{
+ if (join_tab->loosescan_match_tab &&
+ join_tab->loosescan_match_tab->found_match)
+ {
+ KEY *key= join_tab->table->key_info + join_tab->index;
+ key_copy(join_tab->loosescan_buf, info->record, key,
+ join_tab->loosescan_key_len);
+ skip_over= TRUE;
+ }
+
error= info->read_record(info);
+
+ if (skip_over && !error)
+ {
+ if(!key_cmp(join_tab->table->key_info[join_tab->index].key_part,
+ join_tab->loosescan_buf, join_tab->loosescan_key_len))
+ {
+ /*
+ This is the LooseScan action: skip over records with the same key
+ value if we already had a match for them.
+ */
+ continue;
+ }
+ join_tab->loosescan_match_tab->found_match= FALSE;
+ skip_over= FALSE;
+ }
+
+ if (join_tab->keep_current_rowid)
+ join_tab->table->file->position(join_tab->table->record[0]);
+
rc= evaluate_join_record(join, join_tab, error);
}
@@ -11721,16 +13512,23 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if (rc == NESTED_LOOP_NO_MORE_ROWS)
rc= NESTED_LOOP_OK;
- return rc;
+ DBUG_RETURN(rc);
}
/**
- Process one record of the nested loop join.
-
- This function will evaluate parts of WHERE/ON clauses that are
- applicable to the partial record on hand and in case of success
- submit this record to the next level of the nested loop.
+ @brief Process one row of the nested loop join.
+
+ This function will evaluate parts of WHERE/ON clauses that are
+ applicable to the partial row on hand and in case of success
+ submit this row to the next level of the nested loop.
+
+ @param join - The join object
+ @param join_tab - The most inner join_tab being processed
+ @param error > 0: Error, terminate processing
+ = 0: (Partial) row is available
+ < 0: No more rows available at this level
+ @return Nested loop state (Ok, No_more_rows, Error, Killed)
*/
static enum_nested_loop_state
@@ -11742,16 +13540,19 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
COND *select_cond= join_tab->select_cond;
bool select_cond_result= TRUE;
+ DBUG_ENTER("evaluate_join_record");
+ DBUG_PRINT("enter",
+ ("evaluate_join_record join: %p join_tab: %p"
+ " cond: %p error: %d", join, join_tab, select_cond, error));
if (error > 0 || (join->thd->is_error())) // Fatal error
- return NESTED_LOOP_ERROR;
+ DBUG_RETURN(NESTED_LOOP_ERROR);
if (error < 0)
- return NESTED_LOOP_NO_MORE_ROWS;
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
if (join->thd->killed) // Aborted by user
{
join->thd->send_kill_message();
- return NESTED_LOOP_KILLED; /* purecov: inspected */
+ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
}
- DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
update_virtual_fields(join->thd, join_tab->table);
@@ -11761,7 +13562,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
/* check for errors evaluating the condition */
if (join->thd->is_error())
- return NESTED_LOOP_ERROR;
+ DBUG_RETURN(NESTED_LOOP_ERROR);
}
if (!select_cond || select_cond_result)
@@ -11807,7 +13608,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
not to the last table of the current nest level.
*/
join->return_tab= tab;
- return NESTED_LOOP_OK;
+ DBUG_RETURN(NESTED_LOOP_OK);
}
}
}
@@ -11822,7 +13623,26 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
}
if (use_not_exists_opt)
- return NESTED_LOOP_NO_MORE_ROWS;
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ JOIN_TAB *return_tab= join->return_tab;
+ join_tab->found_match= TRUE;
+
+ if (join_tab->check_weed_out_table && found)
+ {
+ int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
+ if (res == -1)
+ DBUG_RETURN(NESTED_LOOP_ERROR);
+ else if (res == 1)
+ found= FALSE;
+ }
+ else if (join_tab->do_firstmatch)
+ {
+ /*
+ We should return to the join_tab->do_firstmatch after we have
+ enumerated all the suffixes for current prefix row combination
+ */
+ return_tab= join_tab->do_firstmatch;
+ }
/*
It was not just a return to lower loop level when one
@@ -11840,16 +13660,19 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
/* A match from join_tab is found for the current partial join. */
rc= (*join_tab->next_select)(join, join_tab+1, 0);
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
- return rc;
+ DBUG_RETURN(rc);
+ if (return_tab < join->return_tab)
+ join->return_tab= return_tab;
+
if (join->return_tab < join_tab)
- return NESTED_LOOP_OK;
+ DBUG_RETURN(NESTED_LOOP_OK);
/*
Test if this was a SELECT DISTINCT query on a table that
was not in the field list; In this case we can abort if
we found a row, as no new rows can be added to the result.
*/
if (not_used_in_distinct && found_records != join->found_records)
- return NESTED_LOOP_NO_MORE_ROWS;
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
}
else
join_tab->read_record.unlock_row(join_tab);
@@ -11864,10 +13687,9 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
join->thd->row_count++;
join_tab->read_record.unlock_row(join_tab);
}
- return NESTED_LOOP_OK;
+ DBUG_RETURN(NESTED_LOOP_OK);
}
-
/**
@details
@@ -11934,101 +13756,6 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
return (*join_tab->next_select)(join, join_tab+1, 0);
}
-
-static enum_nested_loop_state
-flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
-{
- enum_nested_loop_state rc= NESTED_LOOP_OK;
- int error;
- READ_RECORD *info;
- SQL_SELECT *select;
-
- join_tab->table->null_row= 0;
- if (!join_tab->cache.records)
- return NESTED_LOOP_OK; /* Nothing to do */
- if (skip_last)
- (void) store_record_in_cache(&join_tab->cache); // Must save this for later
- if (join_tab->use_quick == 2)
- {
- if (join_tab->select->quick)
- { /* Used quick select last. reset it */
- delete join_tab->select->quick;
- join_tab->select->quick=0;
- }
- }
- /* read through all records */
- if ((error=join_init_read_record(join_tab)))
- {
- reset_cache_write(&join_tab->cache);
- return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
- }
-
- for (JOIN_TAB *tmp=join->join_tab; tmp != join_tab ; tmp++)
- {
- tmp->status=tmp->table->status;
- tmp->table->status=0;
- }
-
- info= &join_tab->read_record;
- select= join_tab->select;
-
- do
- {
- int err= 0;
- if (join->thd->killed)
- {
- join->thd->send_kill_message();
- return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
- }
- if (rc == NESTED_LOOP_OK)
- update_virtual_fields(join->thd, join_tab->table);
- if (rc == NESTED_LOOP_OK &&
- (!join_tab->cache.select ||
- (err= join_tab->cache.select->skip_record(join->thd)) != 0 ))
- {
- if (err < 0)
- {
- reset_cache_write(&join_tab->cache);
- return NESTED_LOOP_ERROR;
- }
-
- reset_cache_read(&join_tab->cache);
- for (uint i= (join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
- {
- read_cached_record(join_tab);
- err= 0;
- if (!select || (err= select->skip_record(join->thd)) != 0)
- {
- if (err < 0)
- {
- reset_cache_write(&join_tab->cache);
- return NESTED_LOOP_ERROR;
- }
- rc= (join_tab->next_select)(join,join_tab+1,0);
- if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
- {
- reset_cache_write(&join_tab->cache);
- return rc;
- }
- }
- }
- }
-
- rc= NESTED_LOOP_OK;
-
- } while (!(error=info->read_record(info)));
-
- if (skip_last)
- read_cached_record(join_tab); // Restore current record
- reset_cache_write(&join_tab->cache);
- if (error > 0) // Fatal error
- return NESTED_LOOP_ERROR; /* purecov: inspected */
- for (JOIN_TAB *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
- tmp2->table->status=tmp2->status;
- return NESTED_LOOP_OK;
-}
-
-
/*****************************************************************************
The different ways to read a record
Returns -1 if row was not found, 0 if row was found and 1 on errors
@@ -12116,7 +13843,14 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
DBUG_RETURN(error);
}
}
- if (*tab->on_expr_ref && !table->null_row)
+ /*
+ Evaluate an on-expression only if it is not considered expensive.
+ This mainly prevents executing subqueries in optimization phase.
+ This is necessary since proper setup for such execution has not been
+ done at this stage.
+ */
+ if (*tab->on_expr_ref && !table->null_row &&
+ !(*tab->on_expr_ref)->is_expensive())
{
#if !defined(DBUG_OFF) && defined(NOT_USING_ITEM_EQUAL)
/*
@@ -12236,25 +13970,49 @@ join_read_const(JOIN_TAB *tab)
return table->status ? -1 : 0;
}
+/*
+ eq_ref access method implementation: "read_first" function
+
+ SYNOPSIS
+ join_read_key()
+ tab JOIN_TAB of the accessed table
+
+ DESCRIPTION
+ This is "read_fist" function for the eq_ref access method. The difference
+ from ref access function is that is that it has a one-element lookup
+ cache (see cmp_buffer_with_ref)
+
+ RETURN
+ 0 - Ok
+ -1 - Row not found
+ 1 - Error
+*/
+
static int
join_read_key(JOIN_TAB *tab)
{
- int error;
- TABLE *table= tab->table;
+ return join_read_key2(tab->join->thd, tab, tab->table, &tab->ref);
+}
+
+/*
+ eq_ref access handler but generalized a bit to support TABLE and TABLE_REF
+ not from the join_tab. See join_read_key for detailed synopsis.
+*/
+int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref)
+{
+ int error;
if (!table->file->inited)
{
- if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))
- {
- table->file->print_error(error, MYF(0));/* purecov: inspected */
- return 1; /* purecov: inspected */
- }
+ table->file->ha_index_init(table_ref->key, (tab ? tab->sorted : TRUE));
}
- if (cmp_buffer_with_ref(tab) ||
+
+ /* TODO: Why don't we do "Late NULLs Filtering" here? */
+ if (cmp_buffer_with_ref(thd, table, table_ref) ||
(table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
{
- if (tab->ref.key_err)
+ if (table_ref->key_err)
{
table->status=STATUS_NOT_FOUND;
return -1;
@@ -12263,28 +14021,28 @@ join_read_key(JOIN_TAB *tab)
Moving away from the current record. Unlock the row
in the handler if it did not match the partial WHERE.
*/
- if (tab->ref.has_record && tab->ref.use_count == 0)
+ if (tab && tab->ref.has_record && tab->ref.use_count == 0)
{
tab->read_record.file->unlock_row();
- tab->ref.has_record= FALSE;
+ table_ref->has_record= FALSE;
}
- error= table->file->ha_index_read_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT);
+ error=table->file->ha_index_read_map(table->record[0],
+ table_ref->key_buff,
+ make_prev_keypart_map(table_ref->key_parts),
+ HA_READ_KEY_EXACT);
if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
if (! error)
{
- tab->ref.has_record= TRUE;
- tab->ref.use_count= 1;
+ table_ref->has_record= TRUE;
+ table_ref->use_count= 1;
}
}
else if (table->status == 0)
{
- DBUG_ASSERT(tab->ref.has_record);
- tab->ref.use_count++;
+ DBUG_ASSERT(table_ref->has_record);
+ table_ref->use_count++;
}
table->null_row=0;
return table->status ? -1 : 0;
@@ -12343,13 +14101,6 @@ join_read_always_key(JOIN_TAB *tab)
}
}
- /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
- for (uint i= 0 ; i < tab->ref.key_parts ; i++)
- {
- if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
- return -1;
- }
-
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
return -1;
if ((error= table->file->ha_index_read_map(table->record[0],
@@ -12455,7 +14206,6 @@ join_init_quick_read_record(JOIN_TAB *tab)
}
-int rr_sequential(READ_RECORD *info);
int init_read_record_seq(JOIN_TAB *tab)
{
tab->read_record.read_record= rr_sequential;
@@ -12470,12 +14220,18 @@ test_if_quick_select(JOIN_TAB *tab)
delete tab->select->quick;
tab->select->quick=0;
return tab->select->test_quick_select(tab->join->thd, tab->keys,
- (table_map) 0, HA_POS_ERROR, 0);
+ (table_map) 0, HA_POS_ERROR, 0,
+ FALSE);
}
-static int
-join_init_read_record(JOIN_TAB *tab)
+static
+bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab)
+{
+ return (join_tab->use_quick == 2 && test_if_quick_select(join_tab) > 0);
+}
+
+int join_init_read_record(JOIN_TAB *tab)
{
if (tab->select && tab->select->quick && tab->select->quick->reset())
return 1;
@@ -12485,6 +14241,12 @@ join_init_read_record(JOIN_TAB *tab)
return (*tab->read_record.read_record)(&tab->read_record);
}
+static int
+join_read_record_no_init(JOIN_TAB *tab)
+{
+ return (*tab->read_record.read_record)(&tab->read_record);
+}
+
static int
join_read_first(JOIN_TAB *tab)
@@ -12730,7 +14492,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/* ARGSUSED */
-static enum_nested_loop_state
+enum_nested_loop_state
end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records)
{
@@ -12889,8 +14651,10 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end;
- if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
- error,1))
+ if (create_internal_tmp_table_from_heap(join->thd, table,
+ join->tmp_table_param.start_recinfo,
+ &join->tmp_table_param.recinfo,
+ error,1))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
table->s->uniques=0; // To ensure rows are the same
}
@@ -12975,7 +14739,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if ((error= table->file->ha_write_row(table->record[0])))
{
if (create_internal_tmp_table_from_heap(join->thd, table,
- &join->tmp_table_param,
+ join->tmp_table_param.start_recinfo,
+ &join->tmp_table_param.recinfo,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
@@ -13042,7 +14807,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/* ARGSUSED */
-static enum_nested_loop_state
+enum_nested_loop_state
end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records)
{
@@ -13075,9 +14840,11 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->having || join->having->val_int())
{
int error= table->file->ha_write_row(table->record[0]);
- if (error && create_internal_tmp_table_from_heap(join->thd, table,
- &join->tmp_table_param,
- error, 0))
+ if (error &&
+ create_internal_tmp_table_from_heap(join->thd, table,
+ join->tmp_table_param.start_recinfo,
+ &join->tmp_table_param.recinfo,
+ error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR);
}
if (join->rollup.state != ROLLUP::STATE_NONE)
@@ -13129,12 +14896,24 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
1 if right_item is used removable reference key on left_item
*/
-static bool test_if_ref(Item_field *left_item,Item *right_item)
+bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
{
Field *field=left_item->field;
- // No need to change const test. We also have to keep tests on LEFT JOIN
- if (!field->table->const_table && !field->table->maybe_null)
+ JOIN_TAB *join_tab= field->table->reginfo.join_tab;
+ // No need to change const test
+ if (!field->table->const_table && join_tab &&
+ (!join_tab->first_inner ||
+ *join_tab->first_inner->on_expr_ref == root_cond))
{
+ // Cond guards
+ for (uint i = 0; i < join_tab->ref.key_parts; i++)
+ {
+ if (join_tab->ref.cond_guards[i])
+ {
+ return FALSE;
+ }
+ }
+ //
Item *ref_item=part_of_refkey(field->table,field);
if (ref_item && ref_item->eq(right_item,1))
{
@@ -13165,10 +14944,181 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
}
+
+/*
+ Extract a condition that can be checked after reading given table
+
+ SYNOPSIS
+ make_cond_for_table()
+ cond Condition to analyze
+ tables Tables for which "current field values" are available
+ used_table Table that we're extracting the condition for (may
+ also include PSEUDO_TABLE_BITS
+ exclude_expensive_cond Do not push expensive conditions
+ retain_ref_cond Retain ref conditions
+
+ DESCRIPTION
+ Extract the condition that can be checked after reading the table
+ specified in 'used_table', given that current-field values for tables
+ specified in 'tables' bitmap are available.
+
+ The function assumes that
+ - Constant parts of the condition has already been checked.
+ - Condition that could be checked for tables in 'tables' has already
+ been checked.
+
+ The function takes into account that some parts of the condition are
+ guaranteed to be true by employed 'ref' access methods (the code that
+ does this is located at the end, search down for "EQ_FUNC").
+
+
+ SEE ALSO
+ make_cond_for_info_schema uses similar algorithm
+
+ RETURN
+ Extracted condition
+*/
+
+static Item *
+make_cond_for_table(Item *cond, table_map tables, table_map used_table,
+ bool exclude_expensive_cond, bool retain_ref_cond)
+{
+ return make_cond_for_table_from_pred(cond, cond, tables, used_table,
+ exclude_expensive_cond,
+ retain_ref_cond);
+}
+
+static Item *
+make_cond_for_table_from_pred(Item *root_cond, Item *cond,
+ table_map tables, table_map used_table,
+ bool exclude_expensive_cond,
+ bool retain_ref_cond)
+
+{
+ if (used_table && !(cond->used_tables() & used_table) &&
+ /*
+ Exclude constant conditions not checked at optimization time if
+ the table we are pushing conditions to is the first one.
+ As a result, such conditions are not considered as already checked
+ and will be checked at execution time, attached to the first table.
+
+ psergey: TODO: "used_table & 1" doesn't make sense in nearly any
+ context. Look at setup_table_map(), table bits reflect the order
+ the tables were encountered by the parser. Check what we should
+ replace this condition with.
+ */
+ !((used_table & 1) && cond->is_expensive()))
+ return (COND*) 0; // Already checked
+ if (cond->type() == Item::COND_ITEM)
+ {
+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
+ {
+ /* Create new top level AND item */
+ Item_cond_and *new_cond=new Item_cond_and;
+ if (!new_cond)
+ return (COND*) 0; // OOM /* purecov: inspected */
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ Item *fix=make_cond_for_table_from_pred(root_cond, item,
+ tables, used_table,
+ exclude_expensive_cond,
+ retain_ref_cond);
+ if (fix)
+ new_cond->argument_list()->push_back(fix);
+ }
+ switch (new_cond->argument_list()->elements) {
+ case 0:
+ return (COND*) 0; // Always true
+ case 1:
+ return new_cond->argument_list()->head();
+ default:
+ /*
+ Item_cond_and do not need fix_fields for execution, its parameters
+ are fixed or do not need fix_fields, too
+ */
+ new_cond->quick_fix_field();
+ new_cond->used_tables_cache=
+ ((Item_cond_and*) cond)->used_tables_cache &
+ tables;
+ return new_cond;
+ }
+ }
+ else
+ { // Or list
+ Item_cond_or *new_cond=new Item_cond_or;
+ if (!new_cond)
+ return (COND*) 0; // OOM /* purecov: inspected */
+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ Item *item;
+ while ((item=li++))
+ {
+ Item *fix=make_cond_for_table_from_pred(root_cond, item,
+ tables, 0L,
+ exclude_expensive_cond,
+ retain_ref_cond);
+ if (!fix)
+ return (COND*) 0; // Always true
+ new_cond->argument_list()->push_back(fix);
+ }
+ /*
+ Item_cond_and do not need fix_fields for execution, its parameters
+ are fixed or do not need fix_fields, too
+ */
+ new_cond->quick_fix_field();
+ new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
+ new_cond->top_level_item();
+ return new_cond;
+ }
+ }
+
+ /*
+ Because the following test takes a while and it can be done
+ table_count times, we mark each item that we have examined with the result
+ of the test
+ */
+ if ((cond->marker == 3 && !retain_ref_cond) ||
+ (cond->used_tables() & ~tables) ||
+ /*
+ When extracting constant conditions, treat expensive conditions as
+ non-constant, so that they are not evaluated at optimization time.
+ */
+ (!used_table && exclude_expensive_cond && cond->is_expensive()))
+ return (COND*) 0; // Can't check this yet
+ if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
+ return cond; // Not boolean op
+
+ if (cond->type() == Item::FUNC_ITEM &&
+ ((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
+ {
+ Item *left_item= ((Item_func*) cond)->arguments()[0]->real_item();
+ Item *right_item= ((Item_func*) cond)->arguments()[1]->real_item();
+ if (left_item->type() == Item::FIELD_ITEM && !retain_ref_cond &&
+ test_if_ref(root_cond, (Item_field*) left_item,right_item))
+ {
+ cond->marker=3; // Checked when read
+ return (COND*) 0;
+ }
+ if (right_item->type() == Item::FIELD_ITEM && !retain_ref_cond &&
+ test_if_ref(root_cond, (Item_field*) right_item,left_item))
+ {
+ cond->marker=3; // Checked when read
+ return (COND*) 0;
+ }
+ }
+ cond->marker=2;
+ return cond;
+}
+
+
+
static COND *
-make_cond_for_table(COND *cond, table_map tables, table_map used_table)
+make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables,
+ table_map sjm_tables)
{
- if (used_table && !(cond->used_tables() & used_table))
+ if ((!(cond->used_tables() & ~tables) ||
+ !(cond->used_tables() & ~sjm_tables)))
return (COND*) 0; // Already checked
if (cond->type() == Item::COND_ITEM)
{
@@ -13182,7 +15132,7 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
Item *item;
while ((item=li++))
{
- Item *fix=make_cond_for_table(item,tables,used_table);
+ Item *fix=make_cond_after_sjm(root_cond, item, tables, sjm_tables);
if (fix)
new_cond->argument_list()->push_back(fix);
}
@@ -13212,7 +15162,7 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
Item *item;
while ((item=li++))
{
- Item *fix=make_cond_for_table(item,tables,0L);
+ Item *fix= make_cond_after_sjm(root_cond, item, tables, 0L);
if (!fix)
return (COND*) 0; // Always true
new_cond->argument_list()->push_back(fix);
@@ -13234,23 +15184,27 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
of the test
*/
- if (cond->marker == 3 || (cond->used_tables() & ~tables))
+ if (cond->marker == 3 || (cond->used_tables() & ~(tables | sjm_tables)))
return (COND*) 0; // Can't check this yet
if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
return cond; // Not boolean op
+ /*
+ Remove equalities that are guaranteed to be true by use of 'ref' access
+ method
+ */
if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
{
- Item *left_item= ((Item_func*) cond)->arguments()[0];
- Item *right_item= ((Item_func*) cond)->arguments()[1];
+ Item *left_item= ((Item_func*) cond)->arguments()[0]->real_item();
+ Item *right_item= ((Item_func*) cond)->arguments()[1]->real_item();
if (left_item->type() == Item::FIELD_ITEM &&
- test_if_ref((Item_field*) left_item,right_item))
+ test_if_ref(root_cond, (Item_field*) left_item,right_item))
{
cond->marker=3; // Checked when read
return (COND*) 0;
}
if (right_item->type() == Item::FIELD_ITEM &&
- test_if_ref((Item_field*) right_item,left_item))
+ test_if_ref(root_cond, (Item_field*) right_item,left_item))
{
cond->marker=3; // Checked when read
return (COND*) 0;
@@ -13260,6 +15214,7 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
return cond;
}
+
static Item *
part_of_refkey(TABLE *table,Field *field)
{
@@ -13647,7 +15602,7 @@ find_field_in_item_list (Field *field, void *data)
static bool
test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
- bool no_changes, key_map *map)
+ bool no_changes, const key_map *map)
{
int ref_key;
uint ref_key_parts;
@@ -13657,6 +15612,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
SQL_SELECT *select=tab->select;
key_map usable_keys;
QUICK_SELECT_I *save_quick= 0;
+ COND *orig_select_cond= 0;
DBUG_ENTER("test_if_skip_sort_order");
LINT_INIT(ref_key_parts);
@@ -13676,7 +15632,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
usable_keys.intersect(((Item_field*) item)->field->part_of_sortkey);
if (usable_keys.is_clear_all())
- DBUG_RETURN(0); // No usable keys
+ goto use_filesort; // No usable keys
}
ref_key= -1;
@@ -13686,7 +15642,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
ref_key= tab->ref.key;
ref_key_parts= tab->ref.key_parts;
if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT)
- DBUG_RETURN(0);
+ goto use_filesort;
}
else if (select && select->quick) // Range found by opt_range
{
@@ -13701,7 +15657,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
- DBUG_RETURN(0);
+ goto use_filesort;
ref_key= select->quick->index;
ref_key_parts= select->quick->used_key_parts;
}
@@ -13723,10 +15679,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
if (table->covering_keys.is_set(ref_key))
usable_keys.intersect(table->covering_keys);
+ if (tab->pre_idx_push_select_cond)
+ orig_select_cond= tab->set_cond(tab->pre_idx_push_select_cond);
+
if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
&usable_keys)) < MAX_KEY)
{
/* Found key that can be used to retrieve data in sorted order */
+ //psergey-mrr:if (tab->pre_idx_push_select_cond)
+ // tab->select_cond= tab->select->cond= tab->pre_idx_push_select_cond;
if (tab->ref.key >= 0)
{
/*
@@ -13740,9 +15701,10 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
KEYUSE *keyuse= tab->keyuse;
while (keyuse->key != new_ref_key && keyuse->table == tab->table)
keyuse++;
+
if (create_ref_for_key(tab->join, tab, keyuse,
tab->join->const_table_map))
- DBUG_RETURN(0);
+ goto use_filesort;
pick_table_access_method(tab);
}
@@ -13764,9 +15726,10 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
(tab->join->select_options &
OPTION_FOUND_ROWS) ?
HA_POS_ERROR :
- tab->join->unit->select_limit_cnt,0) <=
+ tab->join->unit->select_limit_cnt,0,
+ TRUE) <=
0)
- DBUG_RETURN(0);
+ goto use_filesort;
}
ref_key= new_ref_key;
}
@@ -14024,7 +15987,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
join->select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR :
join->unit->select_limit_cnt,
- 0) > 0;
+ TRUE, FALSE) > 0;
}
if (!no_changes)
{
@@ -14047,6 +16010,18 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
if (table->covering_keys.is_set(best_key) && ! table->key_read)
table->enable_keyread();
+ if (tab->pre_idx_push_select_cond)
+ {
+ COND *tmp_cond= tab->pre_idx_push_select_cond;
+ if (orig_select_cond)
+ {
+ tmp_cond= and_conds(tmp_cond, orig_select_cond);
+ tmp_cond->quick_fix_field();
+ }
+ tab->set_cond(tmp_cond);
+ /* orig_select_cond was merged, no need to restore original one. */
+ orig_select_cond= 0;
+ }
table->file->ha_index_or_rnd_end();
if (join->select_options & SELECT_DESCRIBE)
{
@@ -14087,7 +16062,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
saved_best_key_parts : best_key_parts;
}
else
- DBUG_RETURN(0);
+ goto use_filesort;
}
check_reverse_order:
@@ -14102,6 +16077,7 @@ check_reverse_order:
if (!select->quick->reverse_sorted())
{
QUICK_SELECT_DESC *tmp;
+ bool error= FALSE;
int quick_type= select->quick->get_type();
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
@@ -14110,18 +16086,18 @@ check_reverse_order:
{
tab->limit= 0;
select->quick= save_quick;
- DBUG_RETURN(0); // Use filesort
+ goto use_filesort; // Use filesort
}
/* ORDER BY range_key DESC */
tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
- used_key_parts);
- if (!tmp || tmp->error)
+ used_key_parts, &error);
+ if (!tmp || error)
{
delete tmp;
select->quick= save_quick;
tab->limit= 0;
- DBUG_RETURN(0); // Reverse sort not supported
+ goto use_filesort; // Reverse sort not supported
}
select->quick=tmp;
}
@@ -14140,8 +16116,14 @@ check_reverse_order:
}
}
else if (select && select->quick)
- select->quick->sorted= 1;
+ select->quick->need_sorted_output();
+ if (orig_select_cond)
+ tab->set_cond(orig_select_cond);
DBUG_RETURN(1);
+use_filesort:
+ if (orig_select_cond)
+ tab->set_cond(orig_select_cond);
+ DBUG_RETURN(0);
}
@@ -14239,7 +16221,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
field, quick will contain an empty record set.
*/
if (!(select->quick= (tab->type == JT_FT ?
- new FT_SELECT(thd, table, tab->ref.key) :
+ get_ft_select(thd, table, tab->ref.key) :
get_quick_select_for_ref(thd, table, &tab->ref,
tab->found_records))))
goto err;
@@ -14278,7 +16260,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
table->quick_keys.clear_all(); // as far as we cleanup select->quick
table->sort.io_cache= tablesort_result_cache;
}
- tab->select_cond=0;
+ tab->set_select_cond(NULL, __LINE__);
tab->last_inner= 0;
tab->first_unmatched= 0;
tab->type=JT_ALL; // Read with normal read_record
@@ -14302,7 +16284,8 @@ static bool fix_having(JOIN *join, Item **having)
table_map used_tables= join->const_table_map | table->table->map;
DBUG_EXECUTE("where",print_where(*having,"having", QT_ORDINARY););
- Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
+ Item* sort_table_cond=make_cond_for_table(*having, used_tables, used_tables,
+ FALSE, FALSE);
if (sort_table_cond)
{
if (!table->select)
@@ -14315,12 +16298,13 @@ static bool fix_having(JOIN *join, Item **having)
sort_table_cond)) ||
table->select->cond->fix_fields(join->thd, &table->select->cond))
return 1;
- table->select_cond=table->select->cond;
+ table->set_select_cond(table->select->cond, __LINE__);
table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(table->select_cond,
"select and having",
QT_ORDINARY););
- *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
+ *having= make_cond_for_table(*having,~ (table_map) 0,~used_tables,
+ FALSE, FALSE);
DBUG_EXECUTE("where",
print_where(*having,"having after make_cond", QT_ORDINARY););
}
@@ -14668,277 +16652,53 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
}
-/*****************************************************************************
- Fill join cache with packed records
- Records are stored in tab->cache.buffer and last record in
- last record is stored with pointers to blobs to support very big
- records
-******************************************************************************/
-
-static int
-join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
-{
- reg1 uint i;
- uint length, blobs;
- size_t size;
- CACHE_FIELD *copy,**blob_ptr;
- JOIN_CACHE *cache;
- JOIN_TAB *join_tab;
- DBUG_ENTER("join_init_cache");
-
- cache= &tables[table_count].cache;
- cache->fields=blobs=0;
-
- join_tab=tables;
- for (i=0 ; i < table_count ; i++,join_tab++)
- {
- if (!join_tab->used_fieldlength) /* Not calced yet */
- calc_used_field_length(thd, join_tab);
- cache->fields+=join_tab->used_fields;
- blobs+=join_tab->used_blobs;
- }
- if (!(cache->field=(CACHE_FIELD*)
- sql_alloc(sizeof(CACHE_FIELD)*(cache->fields+table_count*2)+(blobs+1)*
- sizeof(CACHE_FIELD*))))
- {
- my_free((uchar*) cache->buff,MYF(0)); /* purecov: inspected */
- cache->buff=0; /* purecov: inspected */
- DBUG_RETURN(1); /* purecov: inspected */
- }
- copy=cache->field;
- blob_ptr=cache->blob_ptr=(CACHE_FIELD**)
- (cache->field+cache->fields+table_count*2);
+/*
+ eq_ref: Create the lookup key and check if it is the same as saved key
- length=0;
- for (i=0 ; i < table_count ; i++)
- {
- bool have_bit_fields= FALSE;
- uint null_fields=0,used_fields;
- Field **f_ptr,*field;
- MY_BITMAP *read_set= tables[i].table->read_set;
- for (f_ptr=tables[i].table->field,used_fields=tables[i].used_fields ;
- used_fields ;
- f_ptr++)
- {
- field= *f_ptr;
- if (bitmap_is_set(read_set, field->field_index))
- {
- used_fields--;
- length+=field->fill_cache_field(copy);
- if (copy->type == CACHE_BLOB)
- (*blob_ptr++)=copy;
- if (field->real_maybe_null())
- null_fields++;
- if (field->type() == MYSQL_TYPE_BIT &&
- ((Field_bit*)field)->bit_len)
- have_bit_fields= TRUE;
- copy++;
- }
- }
- /* Copy null bits from table */
- if (null_fields || have_bit_fields)
- { /* must copy null bits */
- copy->str= tables[i].table->null_flags;
- copy->length= tables[i].table->s->null_bytes;
- copy->type=0;
- copy->field=0;
- length+=copy->length;
- copy++;
- cache->fields++;
- }
- /* If outer join table, copy null_row flag */
- if (tables[i].table->maybe_null)
- {
- copy->str= (uchar*) &tables[i].table->null_row;
- copy->length=sizeof(tables[i].table->null_row);
- copy->type=0;
- copy->field=0;
- length+=copy->length;
- copy++;
- cache->fields++;
- }
- }
- cache->length=length+blobs*sizeof(char*);
- cache->blobs=blobs;
- *blob_ptr=0; /* End sequentel */
- size=max(thd->variables.join_buff_size, cache->length);
- if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
- DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
- cache->end=cache->buff+size;
- reset_cache_write(cache);
- DBUG_RETURN(0);
-}
-static ulong
-used_blob_length(CACHE_FIELD **ptr)
-{
- uint length,blob_length;
- for (length=0 ; *ptr ; ptr++)
- {
- Field_blob *field_blob= (Field_blob *) (*ptr)->field;
- (*ptr)->blob_length=blob_length= field_blob->get_length();
- length+=blob_length;
- field_blob->get_ptr(&(*ptr)->str);
- }
- return length;
-}
+ SYNOPSIS
+ cmp_buffer_with_ref()
+ tab Join tab of the accessed table
+ table The table to read. This is usually tab->table, except for
+ semi-join when we might need to make a lookup in a temptable
+ instead.
+ tab_ref The structure with methods to collect index lookup tuple.
+ This is usually table->ref, except for the case of when we're
+ doing lookup into semi-join materialization table.
+
+ DESCRIPTION
+ Used by eq_ref access method: create the index lookup key and check if
+ we've used this key at previous lookup (If yes, we don't need to repeat
+ the lookup - the record has been already fetched)
+ RETURN
+ TRUE No cached record for the key, or failed to create the key (due to
+ out-of-domain error)
+ FALSE The created key is the same as the previous one (and the record
+ is already in table->record)
+*/
static bool
-store_record_in_cache(JOIN_CACHE *cache)
+cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref)
{
- uint length;
- uchar *pos;
- CACHE_FIELD *copy,*end_field;
- bool last_record;
-
- pos=cache->pos;
- end_field=cache->field+cache->fields;
-
- length=cache->length;
- if (cache->blobs)
- length+=used_blob_length(cache->blob_ptr);
- if ((last_record= (length + cache->length > (size_t) (cache->end - pos))))
- cache->ptr_record=cache->records;
-
- /*
- There is room in cache. Put record there
- */
- cache->records++;
- for (copy=cache->field ; copy < end_field; copy++)
+ bool no_prev_key;
+ if (!tab_ref->disable_cache)
{
- if (copy->type == CACHE_BLOB)
+ if (!(no_prev_key= tab_ref->key_err))
{
- Field_blob *blob_field= (Field_blob *) copy->field;
- if (last_record)
- {
- blob_field->get_image(pos, copy->length+sizeof(char*),
- blob_field->charset());
- pos+=copy->length+sizeof(char*);
- }
- else
- {
- blob_field->get_image(pos, copy->length, // blob length
- blob_field->charset());
- memcpy(pos+copy->length,copy->str,copy->blob_length); // Blob data
- pos+=copy->length+copy->blob_length;
- }
- }
- else
- {
- if (copy->type == CACHE_STRIPPED)
- {
- uchar *str,*end;
- Field *field= copy->field;
- if (field && field->is_null())
- end= str= copy->str;
- else
- {
- for (str=copy->str,end= str+copy->length;
- end > str && end[-1] == ' ' ;
- end--)
- ;
- }
- length=(uint) (end-str);
- memcpy(pos+2, str, length);
- int2store(pos, length);
- pos+= length+2;
- }
- else
- {
- memcpy(pos,copy->str,copy->length);
- pos+=copy->length;
- }
- }
- }
- cache->pos=pos;
- return last_record || (size_t) (cache->end - pos) < cache->length;
-}
-
-
-static void
-reset_cache_read(JOIN_CACHE *cache)
-{
- cache->record_nr=0;
- cache->pos=cache->buff;
-}
-
-
-static void reset_cache_write(JOIN_CACHE *cache)
-{
- reset_cache_read(cache);
- cache->records= 0;
- cache->ptr_record= (uint) ~0;
-}
-
-
-static void
-read_cached_record(JOIN_TAB *tab)
-{
- uchar *pos;
- uint length;
- bool last_record;
- CACHE_FIELD *copy,*end_field;
-
- last_record=tab->cache.record_nr++ == tab->cache.ptr_record;
- pos=tab->cache.pos;
-
- for (copy=tab->cache.field,end_field=copy+tab->cache.fields ;
- copy < end_field;
- copy++)
- {
- if (copy->type == CACHE_BLOB)
- {
- Field_blob *blob_field= (Field_blob *) copy->field;
- if (last_record)
- {
- blob_field->set_image(pos, copy->length+sizeof(char*),
- blob_field->charset());
- pos+=copy->length+sizeof(char*);
- }
- else
- {
- blob_field->set_ptr(pos, pos+copy->length);
- pos+=copy->length + blob_field->get_length();
- }
- }
- else
- {
- if (copy->type == CACHE_STRIPPED)
- {
- length= uint2korr(pos);
- memcpy(copy->str, pos+2, length);
- memset(copy->str+length, ' ', copy->length-length);
- pos+= 2 + length;
- }
- else
- {
- memcpy(copy->str,pos,copy->length);
- pos+=copy->length;
- }
+ /* Previous access found a row. Copy its key */
+ memcpy(tab_ref->key_buff2, tab_ref->key_buff, tab_ref->key_length);
}
}
- tab->cache.pos=pos;
- return;
-}
-
-
-static bool
-cmp_buffer_with_ref(JOIN_TAB *tab)
-{
- bool diff;
- if (!(diff=tab->ref.key_err))
- {
- memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length);
- }
- if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, tab->table,
- &tab->ref)) ||
- diff)
+ else
+ no_prev_key= TRUE;
+ if ((tab_ref->key_err= cp_buffer_from_ref(thd, table, tab_ref)) ||
+ no_prev_key)
return 1;
- return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
+ return memcmp(tab_ref->key_buff2, tab_ref->key_buff, tab_ref->key_length)
!= 0;
}
@@ -15634,7 +17394,7 @@ alloc_group_fields(JOIN *join,ORDER *group)
{
for (; group ; group=group->next)
{
- Cached_item *tmp=new_Cached_item(join->thd, *group->item);
+ Cached_item *tmp=new_Cached_item(join->thd, *group->item, TRUE);
if (!tmp || join->group_fields.push_front(tmp))
return TRUE;
}
@@ -15644,6 +17404,38 @@ alloc_group_fields(JOIN *join,ORDER *group)
}
+
+/*
+ Test if a single-row cache of items changed, and update the cache.
+
+ @details Test if a list of items that typically represents a result
+ row has changed. If the value of some item changed, update the cached
+ value for this item.
+
+ @param list list of <item, cached_value> pairs stored as Cached_item.
+
+ @return -1 if no item changed
+ @return index of the first item that changed
+*/
+
+int test_if_item_cache_changed(List<Cached_item> &list)
+{
+ DBUG_ENTER("test_if_item_cache_changed");
+ List_iterator<Cached_item> li(list);
+ int idx= -1,i;
+ Cached_item *buff;
+
+ for (i=(int) list.elements-1 ; (buff=li++) ; i--)
+ {
+ if (buff->cmp())
+ idx=i;
+ }
+ DBUG_PRINT("info", ("idx: %d", idx));
+ DBUG_RETURN(idx);
+}
+
+
+
static int
test_if_group_changed(List<Cached_item> &list)
{
@@ -15784,6 +17576,8 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
}
else if ((real_pos->type() == Item::FUNC_ITEM ||
real_pos->type() == Item::SUBSELECT_ITEM ||
+ (real_pos->get_cached_item() &&
+ real_pos->get_cached_item()->type() == Item::SUBSELECT_ITEM) ||
real_pos->type() == Item::CACHE_ITEM ||
real_pos->type() == Item::COND_ITEM) &&
!real_pos->with_sum_func)
@@ -16026,6 +17820,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
char buff[256];
String str(buff,sizeof(buff),&my_charset_bin);
str.length(0);
+ str.extra_allocation(1024);
item->print(&str, QT_ORDINARY);
item_field->name= sql_strmake(str.ptr(),str.length());
}
@@ -16256,11 +18051,12 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
{
if (join_tab->select->cond)
error=(int) cond->add(join_tab->select->cond);
- join_tab->select_cond=join_tab->select->cond=cond;
+ join_tab->select->cond= cond;
+ join_tab->set_select_cond(cond, __LINE__);
}
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
&error)))
- join_tab->select_cond=cond;
+ join_tab->set_select_cond(cond, __LINE__);
DBUG_RETURN(error ? TRUE : FALSE);
}
@@ -16717,8 +18513,10 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
{
- if (create_internal_tmp_table_from_heap(thd, table_arg, &tmp_table_param,
- write_error, 0))
+ if (create_internal_tmp_table_from_heap(thd, table_arg,
+ tmp_table_param.start_recinfo,
+ &tmp_table_param.recinfo,
+ write_error, 0))
return 1;
}
}
@@ -16864,7 +18662,15 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
else
{
table_map used_tables=0;
- for (uint i=0 ; i < join->tables ; i++)
+
+ uchar sjm_nests[MAX_TABLES];
+ uint sjm_nests_cur=0;
+ uint sjm_nests_end= 0;
+ uint end_table= join->tables;
+ bool printing_materialize_nest= FALSE;
+ uint select_id= join->select_lex->select_number;
+
+ for (uint i=0 ; i < end_table ; i++)
{
JOIN_TAB *tab=join->join_tab+i;
TABLE *table=tab->table;
@@ -16872,6 +18678,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
char buff[512];
char buff1[512], buff2[512], buff3[512];
char keylen_str_buf[64];
+ my_bool key_read;
String extra(buff, sizeof(buff),cs);
char table_name_buffer[SAFE_NAME_LEN];
String tmp1(buff1,sizeof(buff1),cs);
@@ -16881,7 +18688,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
tmp1.length(0);
tmp2.length(0);
tmp3.length(0);
-
quick_type= -1;
/* Don't show eliminated tables */
@@ -16893,12 +18699,90 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list.empty();
/* id */
- item_list.push_back(new Item_uint((uint32)
- join->select_lex->select_number));
+ item_list.push_back(new Item_uint((uint32)select_id));
/* select_type */
- item_list.push_back(new Item_string(join->select_lex->type,
- strlen(join->select_lex->type),
- cs));
+ const char* stype= printing_materialize_nest? "SUBQUERY" :
+ join->select_lex->type;
+ item_list.push_back(new Item_string(stype, strlen(stype), cs));
+
+ /*
+ Special processing for SJ-Materialization nests: print the fake table
+ and delay printing of the SJM nest contents until later.
+ */
+ uint sj_strategy= join->best_positions[i].sj_strategy;
+ if (sj_is_materialize_strategy(sj_strategy) &&
+ !printing_materialize_nest)
+ {
+ /* table */
+ int len= my_snprintf(table_name_buffer,
+ sizeof(table_name_buffer)-1,
+ "subselect%d",
+ tab->emb_sj_nest->sj_subq_pred->get_identifier());
+ item_list.push_back(new Item_string(table_name_buffer, len, cs));
+ /* partitions */
+ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
+ item_list.push_back(item_null);
+ /* type */
+ uint type= (sj_strategy == SJ_OPT_MATERIALIZE_SCAN)? JT_ALL : JT_EQ_REF;
+ item_list.push_back(new Item_string(join_type_str[type],
+ strlen(join_type_str[type]),
+ cs));
+ /* possible_keys */
+ item_list.push_back(new Item_string("unique_key",
+ strlen("unique_key"), cs));
+ if (sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
+ {
+ item_list.push_back(item_null); /* key */
+ item_list.push_back(item_null); /* key_len */
+ item_list.push_back(item_null); /* ref */
+ }
+ else
+ {
+ /* key */
+ item_list.push_back(new Item_string("unique_key", strlen("unique_key"), cs));
+ /* key_len */
+ uint klen= tab->emb_sj_nest->sj_mat_info->table->key_info[0].key_length;
+ uint buflen= longlong10_to_str(klen, keylen_str_buf, 10) - keylen_str_buf;
+ item_list.push_back(new Item_string(keylen_str_buf, buflen, cs));
+ /* ref */
+ item_list.push_back(new Item_string("func", strlen("func"), cs));
+ }
+ /* rows */
+ ha_rows rows= (ha_rows) ((sj_strategy == SJ_OPT_MATERIALIZE_SCAN)?
+ tab->emb_sj_nest->sj_mat_info->rows : 1.0);
+ item_list.push_back(new Item_int((longlong)rows,
+ MY_INT64_NUM_DECIMAL_DIGITS));
+ /* filtered */
+ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
+ item_list.push_back(new Item_float(1.0, 2));
+
+ /* Extra */
+ if (need_tmp_table)
+ {
+ need_tmp_table=0;
+ extra.append(STRING_WITH_LEN("; Using temporary"));
+ }
+ if (need_order)
+ {
+ need_order=0;
+ extra.append(STRING_WITH_LEN("; Using filesort"));
+ }
+ /* Skip initial "; "*/
+ const char *str= extra.ptr();
+ uint32 extra_len= extra.length();
+ if (extra_len)
+ {
+ str += 2;
+ extra_len -= 2;
+ }
+ item_list.push_back(new Item_string(str, extra_len, cs));
+
+ /* Register the nest for further processing: */
+ sjm_nests[sjm_nests_end++]= i;
+ i += join->best_positions[i].n_sj_tables-1;
+ goto loop_end;
+ }
+
if (tab->type == JT_ALL && tab->select && tab->select->quick)
{
quick_type= tab->select->quick->get_type();
@@ -16909,6 +18793,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
else
tab->type = JT_RANGE;
}
+
/* table */
if (table->derived_select_number)
{
@@ -17075,6 +18960,17 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
/* Add "filtered" field to item_list. */
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
{
+ /*
+ psergey-todo:
+ in the code above, we cast to integer when asssigning to
+ examined_rows.
+ In the code below, we may divide original value but result of
+ conversion of the same value to integer, which may produce a
+ value that's greater than 100%, which looks very odd.
+ I'm not fixing this right away because that might trigger a wave
+ of small EXPLAIN EXTENDED output changes, which I don't have time
+ to deal with right now.
+ */
float f= 0.0;
if (examined_rows)
f= (float) (100.0 * join->best_positions[i].records_read /
@@ -17084,7 +18980,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
/* Build "Extra" field and add it to item_list. */
- my_bool key_read=table->key_read;
+ key_read=table->key_read;
if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
table->covering_keys.is_set(tab->index))
key_read=1;
@@ -17114,6 +19010,18 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
else
{
+ uint keyno= MAX_KEY;
+ if (tab->ref.key_parts)
+ keyno= tab->ref.key;
+ else if (tab->select && tab->select->quick)
+ keyno = tab->select->quick->index;
+
+ if (keyno != MAX_KEY && keyno == table->file->pushed_idx_cond_keyno &&
+ table->file->pushed_idx_cond)
+ extra.append(STRING_WITH_LEN("; Using index condition"));
+ else if (tab->cache_idx_cond)
+ extra.append(STRING_WITH_LEN("; Using index condition(BKA)"));
+
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
@@ -17177,6 +19085,14 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
if (table->reginfo.not_exists_optimize)
extra.append(STRING_WITH_LEN("; Not exists"));
+
+ if (quick_type == QUICK_SELECT_I::QS_TYPE_RANGE &&
+ !(((QUICK_RANGE_SELECT*)(tab->select->quick))->mrr_flags &
+ HA_MRR_USE_DEFAULT_IMPL))
+ {
+ extra.append(STRING_WITH_LEN("; Using MRR"));
+ }
+
if (need_tmp_table)
{
need_tmp_table=0;
@@ -17189,6 +19105,56 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
if (distinct & test_all_bits(used_tables,thd->used_tables))
extra.append(STRING_WITH_LEN("; Distinct"));
+ if (tab->loosescan_match_tab)
+ {
+ extra.append(STRING_WITH_LEN("; LooseScan"));
+ }
+
+ if (tab->flush_weedout_table)
+ extra.append(STRING_WITH_LEN("; Start temporary"));
+ if (tab->check_weed_out_table)
+ extra.append(STRING_WITH_LEN("; End temporary"));
+ else if (tab->do_firstmatch)
+ {
+ if (tab->do_firstmatch == join->join_tab - 1)
+ extra.append(STRING_WITH_LEN("; FirstMatch"));
+ else
+ {
+ extra.append(STRING_WITH_LEN("; FirstMatch("));
+ TABLE *prev_table=tab->do_firstmatch->table;
+ if (prev_table->derived_select_number)
+ {
+ char namebuf[NAME_LEN];
+ /* Derived table name generation */
+ int len= my_snprintf(namebuf, sizeof(namebuf)-1,
+ "<derived%u>",
+ prev_table->derived_select_number);
+ extra.append(namebuf, len);
+ }
+ else
+ extra.append(prev_table->pos_in_table_list->alias);
+ extra.append(STRING_WITH_LEN(")"));
+ }
+ }
+
+ /*
+ if (sj_is_materialize_strategy(sj_strategy))
+ {
+ if (join->best_positions[i].n_sj_tables == 1)
+ extra.append(STRING_WITH_LEN("; Materialize"));
+ else
+ {
+ last_sjm_table= i + join->best_positions[i].n_sj_tables - 1;
+ extra.append(STRING_WITH_LEN("; Start materialize"));
+ }
+ if (sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
+ extra.append(STRING_WITH_LEN("; Scan"));
+ }
+ else if (last_sjm_table == i)
+ {
+ extra.append(STRING_WITH_LEN("; End materialize"));
+ }
+ */
for (uint part= 0; part < tab->ref.key_parts; part++)
{
@@ -17198,8 +19164,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
break;
}
}
- if (i > 0 && tab[-1].next_select == sub_select_cache)
+
+ if (tab->cache)
+ {
extra.append(STRING_WITH_LEN("; Using join buffer"));
+ tab->cache->print_explain_comment(&extra);
+ }
/* Skip initial "; "*/
const char *str= extra.ptr();
@@ -17211,6 +19181,15 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
item_list.push_back(new Item_string(str, len, cs));
}
+ loop_end:
+ if (i+1 == end_table && sjm_nests_cur != sjm_nests_end)
+ {
+ printing_materialize_nest= TRUE;
+ i= sjm_nests[sjm_nests_cur++] - 1;
+ end_table= (i+1) + join->best_positions[i+1].n_sj_tables;
+ select_id= join->join_tab[i+1].emb_sj_nest->sj_subq_pred->get_identifier();
+ }
+
// For next iteration
used_tables|=table->map;
if (result->send_data(item_list))
@@ -17221,6 +19200,26 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
unit;
unit= unit->next_unit())
{
+ /*
+ This fix_fields() call is to handle an edge case like this:
+
+ SELECT ... UNION SELECT ... ORDER BY (SELECT ...)
+
+ for such queries, we'll get here before having called
+ subquery_expr->fix_fields(), which will cause failure to
+ */
+ if (unit->item && !unit->item->fixed)
+ {
+ Item *ref= unit->item;
+ if (unit->item->fix_fields(thd, &ref))
+ DBUG_VOID_RETURN;
+ DBUG_ASSERT(ref == unit->item);
+ }
+
+ /*
+ Display subqueries only if they are not parts of eliminated WHERE/ON
+ clauses.
+ */
if (!(unit->item && unit->item->eliminated))
{
if (mysql_explain_union(thd, unit, result))
@@ -17288,6 +19287,53 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
}
+static void print_table_array(THD *thd,
+ table_map eliminated_tables,
+ String *str, TABLE_LIST **table,
+ TABLE_LIST **end,
+ enum_query_type query_type)
+{
+ (*table)->print(thd, eliminated_tables, str, query_type);
+
+ for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
+ {
+ TABLE_LIST *curr= *tbl;
+
+ /*
+ The "eliminated_tables &&" check guards againist the case of
+ printing the query for CREATE VIEW. We do that without having run
+ JOIN::optimize() and so will have nested_join->used_tables==0.
+ */
+ if (eliminated_tables &&
+ ((curr->table && (curr->table->map & eliminated_tables)) ||
+ (curr->nested_join && !(curr->nested_join->used_tables &
+ ~eliminated_tables))))
+ {
+ continue;
+ }
+
+ if (curr->outer_join)
+ {
+ /* MySQL converts right to left joins */
+ str->append(STRING_WITH_LEN(" left join "));
+ }
+ else if (curr->straight)
+ str->append(STRING_WITH_LEN(" straight_join "));
+ else if (curr->sj_inner_tables)
+ str->append(STRING_WITH_LEN(" semi join "));
+ else
+ str->append(STRING_WITH_LEN(" join "));
+ curr->print(thd, eliminated_tables, str, query_type);
+ if (curr->on_expr)
+ {
+ str->append(STRING_WITH_LEN(" on("));
+ curr->on_expr->print(str, query_type);
+ str->append(')');
+ }
+ }
+}
+
+
/**
Print joins from the FROM clause.
@@ -17322,45 +19368,28 @@ static void print_join(THD *thd,
!(((*table)->table && ((*table)->table->map & eliminated_tables)) ||
((*table)->nested_join && !((*table)->nested_join->used_tables &
~eliminated_tables))));
- (*table)->print(thd, eliminated_tables, str, query_type);
-
- TABLE_LIST **end= table + tables->elements;
- for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
+ /*
+ If the first table is a semi-join nest, swap it with something that is
+ not a semi-join nest.
+ */
+ if ((*table)->sj_inner_tables)
{
- TABLE_LIST *curr= *tbl;
- /*
- The "eliminated_tables &&" check guards againist the case of
- printing the query for CREATE VIEW. We do that without having run
- JOIN::optimize() and so will have nested_join->used_tables==0.
- */
- if (eliminated_tables &&
- ((curr->table && (curr->table->map & eliminated_tables)) ||
- (curr->nested_join && !(curr->nested_join->used_tables &
- ~eliminated_tables))))
+ TABLE_LIST **end= table + tables->elements;
+ for (TABLE_LIST **t2= table; t2!=end; t2++)
{
- continue;
- }
-
- if (curr->outer_join)
- {
- /* MySQL converts right to left joins */
- str->append(STRING_WITH_LEN(" left join "));
- }
- else if (curr->straight)
- str->append(STRING_WITH_LEN(" straight_join "));
- else
- str->append(STRING_WITH_LEN(" join "));
- curr->print(thd, eliminated_tables, str, query_type);
- if (curr->on_expr)
- {
- str->append(STRING_WITH_LEN(" on("));
- curr->on_expr->print(str, query_type);
- str->append(')');
+ if (!(*t2)->sj_inner_tables)
+ {
+ TABLE_LIST *tmp= *t2;
+ *t2= *table;
+ *table= tmp;
+ break;
+ }
}
}
+ print_table_array(thd, eliminated_tables, str, table,
+ table + tables->elements, query_type);
}
-
/**
@brief Print an index hint
@@ -17495,9 +19524,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
{
- /* QQ: thd may not be set for sub queries, but this should be fixed */
- if (!thd)
- thd= current_thd;
+ DBUG_ASSERT(thd);
str->append(STRING_WITH_LEN("select "));
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 2a9af48f1cd..ecc19f763fa 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -14,6 +14,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#ifndef SQL_SELECT_INCLUDED
+#define SQL_SELECT_INCLUDED
/**
@file
@@ -28,6 +30,16 @@
#include "procedure.h"
#include <myisam.h>
+#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+#include "../storage/maria/ha_maria.h"
+#define TMP_ENGINE_HTON maria_hton
+#else
+#define TMP_ENGINE_HTON myisam_hton
+#endif
+/* Values in optimize */
+#define KEY_OPTIMIZE_EXISTS 1
+#define KEY_OPTIMIZE_REF_OR_NULL 2
+
typedef struct keyuse_t {
TABLE *table;
Item *val; /**< or value if no field */
@@ -51,6 +63,11 @@ typedef struct keyuse_t {
NULL - Otherwise (the source equality can't be turned off)
*/
bool *cond_guard;
+ /*
+ 0..64 <=> This was created from semi-join IN-equality # sj_pred_no.
+ MAX_UINT Otherwise
+ */
+ uint sj_pred_no;
} KEYUSE;
class store_key;
@@ -92,32 +109,17 @@ typedef struct st_table_ref
in the join.
*/
ha_rows use_count;
-} TABLE_REF;
-
-
-
-#define CACHE_BLOB 1 /* blob field */
-#define CACHE_STRIPPED 2 /* field stripped of trailing spaces */
-
-/**
- CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
- table
-*/
-typedef struct st_cache_field {
- uchar *str;
- uint length, blob_length;
- Field *field;
- uint type; /**< category of the of the copied field (CACHE_BLOB et al.) */
-} CACHE_FIELD;
+ /*
+ TRUE <=> disable the "cache" as doing lookup with the same key value may
+ produce different results (because of Index Condition Pushdown)
+ */
+ bool disable_cache;
-typedef struct st_join_cache {
- uchar *buff,*pos,*end;
- uint records,record_nr,ptr_record,fields,length,blobs;
- CACHE_FIELD *field,**blob_ptr;
- SQL_SELECT *select;
-} JOIN_CACHE;
+ bool tmp_table_index_lookup_init(THD *thd, KEY *tmp_key, Item_iterator &it,
+ bool value);
+} TABLE_REF;
/*
@@ -147,17 +149,29 @@ typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
typedef int (*Read_record_func)(struct st_join_table *tab);
Next_select_func setup_end_select_func(JOIN *join);
+int rr_sequential(READ_RECORD *info);
+
+class JOIN_CACHE;
+class SJ_TMP_TABLE;
typedef struct st_join_table {
st_join_table() {} /* Remove gcc warning */
TABLE *table;
KEYUSE *keyuse; /**< pointer to first used key */
SQL_SELECT *select;
- COND *select_cond;
+ COND *select_cond;
COND *on_precond; /**< part of on condition to check before
accessing the first inner table */
QUICK_SELECT_I *quick;
+ /*
+ The value of select_cond before we've attempted to do Index Condition
+ Pushdown. We may need to restore everything back if we first choose one
+ index but then reconsider (see test_if_skip_sort_order() for such
+ scenarios).
+ NULL means no index condition pushdown was performed.
+ */
+ Item *pre_idx_push_select_cond;
Item **on_expr_ref; /**< pointer to the associated on expression */
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
st_join_table *first_inner; /**< first inner table for including outerjoin */
@@ -204,11 +218,19 @@ typedef struct st_join_table {
E(#records) is in found_records.
*/
ha_rows read_time;
-
+
+ double partial_join_cardinality;
+
table_map dependent,key_dependent;
uint use_quick,index;
uint status; ///< Save status for cache
- uint used_fields,used_fieldlength,used_blobs;
+ uint used_fields;
+ ulong used_fieldlength;
+ 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;
bool sorted;
@@ -219,11 +241,73 @@ typedef struct st_join_table {
*/
ha_rows limit;
TABLE_REF ref;
- JOIN_CACHE cache;
+ bool use_join_cache;
+ ulong join_buffer_size_limit;
+ JOIN_CACHE *cache;
+ /*
+ Index condition for BKA access join
+ */
+ Item *cache_idx_cond;
+ SQL_SELECT *cache_select;
JOIN *join;
- /** Bitmap of nested joins this table is part of */
+ /*
+ Embedding SJ-nest (may be not the direct parent), or NULL if none.
+ This variable holds the result of table pullout.
+ */
+ TABLE_LIST *emb_sj_nest;
+
+ /* FirstMatch variables (final QEP) */
+ struct st_join_table *first_sj_inner_tab;
+ struct st_join_table *last_sj_inner_tab;
+
+ /* Variables for semi-join duplicate elimination */
+ SJ_TMP_TABLE *flush_weedout_table;
+ SJ_TMP_TABLE *check_weed_out_table;
+
+ /*
+ If set, means we should stop join enumeration after we've got the first
+ match and return to the specified join tab. May point to
+ join->join_tab[-1] which means stop join execution after the first
+ match.
+ */
+ struct st_join_table *do_firstmatch;
+
+ /*
+ ptr - We're doing a LooseScan, this join tab is the first (i.e.
+ "driving") join tab), and ptr points to the last join tab
+ handled by the strategy. loosescan_match_tab->found_match
+ should be checked to see if the current value group had a match.
+ NULL - Not doing a loose scan on this join tab.
+ */
+ struct st_join_table *loosescan_match_tab;
+
+ /* Buffer to save index tuple to be able to skip duplicates */
+ uchar *loosescan_buf;
+
+ /* Length of key tuple (depends on #keyparts used) to store in the above */
+ uint loosescan_key_len;
+
+ /* Used by LooseScan. TRUE<=> there has been a matching record combination */
+ bool found_match;
+
+ /*
+ Used by DuplicateElimination. tab->table->ref must have the rowid
+ whenever we have a current record.
+ */
+ int keep_current_rowid;
+
+ /* NestedOuterJoins: Bitmap of nested joins this table is part of */
nested_join_map embedding_map;
+ /*
+ Semi-join strategy to be used for this join table. This is a copy of
+ POSITION::sj_strategy field. This field is set up by the
+ fix_semijion_strategies_for_picked_join_order.
+ */
+ uint sj_strategy;
+
+ struct st_join_table *first_sjm_sibling;
+
void cleanup();
inline bool is_using_loose_index_scan()
{
@@ -231,12 +315,118 @@ typedef struct st_join_table {
(select->quick->get_type() ==
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
}
+ bool check_rowid_field()
+ {
+ if (keep_current_rowid && !used_rowid_fields)
+ {
+ used_rowid_fields= 1;
+ used_fieldlength+= table->file->ref_length;
+ }
+ return test(used_rowid_fields);
+ }
+ bool is_inner_table_of_semi_join_with_first_match()
+ {
+ return first_sj_inner_tab != NULL;
+ }
+ bool is_inner_table_of_outer_join()
+ {
+ return first_inner != NULL;
+ }
+ bool is_single_inner_of_semi_join_with_first_match()
+ {
+ return first_sj_inner_tab == this && last_sj_inner_tab == this;
+ }
+ bool is_single_inner_of_outer_join()
+ {
+ return first_inner == this && first_inner->last_inner == this;
+ }
+ bool is_first_inner_for_outer_join()
+ {
+ return first_inner && first_inner == this;
+ }
+ bool use_match_flag()
+ {
+ return is_first_inner_for_outer_join() || first_sj_inner_tab == this ;
+ }
+ bool check_only_first_match()
+ {
+ return is_inner_table_of_semi_join_with_first_match() ||
+ (is_inner_table_of_outer_join() &&
+ table->reginfo.not_exists_optimize);
+ }
+ bool is_last_inner_table()
+ {
+ return (first_inner && first_inner->last_inner == this) ||
+ last_sj_inner_tab == this;
+ }
+ /*
+ Check whether the table belongs to a nest of inner tables of an
+ outer join or to a nest of inner tables of a semi-join
+ */
+ bool is_nested_inner()
+ {
+ if (first_inner &&
+ (first_inner != first_inner->last_inner || first_inner->first_upper))
+ return TRUE;
+ if (first_sj_inner_tab && first_sj_inner_tab != last_sj_inner_tab)
+ return TRUE;
+ return FALSE;
+ }
+ struct st_join_table *get_first_inner_table()
+ {
+ if (first_inner)
+ return first_inner;
+ return first_sj_inner_tab;
+ }
+ void set_select_cond(COND *to, uint line)
+ {
+ DBUG_PRINT("info", ("select_cond changes %p -> %p at line %u tab %p",
+ select_cond, to, line, this));
+ select_cond= to;
+ }
+ COND *set_cond(COND *new_cond)
+ {
+ COND *tmp_select_cond= select_cond;
+ set_select_cond(new_cond, __LINE__);
+ if (select)
+ select->cond= new_cond;
+ return tmp_select_cond;
+ }
+ void calc_used_field_length(bool max_fl);
+ ulong get_used_fieldlength()
+ {
+ if (!used_fieldlength)
+ calc_used_field_length(FALSE);
+ return used_fieldlength;
+ }
+ ulong get_max_used_fieldlength()
+ {
+ if (!max_used_fieldlength)
+ calc_used_field_length(TRUE);
+ return max_used_fieldlength;
+ }
+ double get_partial_join_cardinality() { return partial_join_cardinality; }
+ bool hash_join_is_possible();
+ int make_scan_filter();
} JOIN_TAB;
+
+#include "sql_join_cache.h"
+
enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
end_of_records);
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
end_of_records);
+enum_nested_loop_state sub_select_sjm(JOIN *join, JOIN_TAB *join_tab,
+ bool end_of_records);
+
+enum_nested_loop_state
+end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
+ bool end_of_records);
+enum_nested_loop_state
+end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
+ bool end_of_records);
+
/**
Information about a position of table within a join order. Used in join
@@ -267,6 +457,89 @@ typedef struct st_position
/* If ref-based access is used: bitmap of tables this table depends on */
table_map ref_depend_map;
+
+ bool use_join_buffer;
+
+
+ /* These form a stack of partial join order costs and output sizes */
+ COST_VECT prefix_cost;
+ double prefix_record_count;
+
+ /*
+ Current optimization state: Semi-join strategy to be used for this
+ and preceding join tables.
+
+ Join optimizer sets this for the *last* join_tab in the
+ duplicate-generating range. That is, in order to interpret this field,
+ one needs to traverse join->[best_]positions array from right to left.
+ When you see a join table with sj_strategy!= SJ_OPT_NONE, some other
+ field (depending on the strategy) tells how many preceding positions
+ this applies to. The values of covered_preceding_positions->sj_strategy
+ must be ignored.
+ */
+ uint sj_strategy;
+ /*
+ Valid only after fix_semijoin_strategies_for_picked_join_order() call:
+ if sj_strategy!=SJ_OPT_NONE, this is the number of subsequent tables that
+ are covered by the specified semi-join strategy
+ */
+ uint n_sj_tables;
+
+/* LooseScan strategy members */
+
+ /* The first (i.e. driving) table we're doing loose scan for */
+ uint first_loosescan_table;
+ /*
+ Tables that need to be in the prefix before we can calculate the cost
+ of using LooseScan strategy.
+ */
+ table_map loosescan_need_tables;
+
+ /*
+ keyno - Planning to do LooseScan on this key. If keyuse is NULL then
+ this is a full index scan, otherwise this is a ref+loosescan
+ scan (and keyno matches the KEUSE's)
+ MAX_KEY - Not doing a LooseScan
+ */
+ uint loosescan_key; // final (one for strategy instance )
+ uint loosescan_parts; /* Number of keyparts to be kept distinct */
+
+/* FirstMatch strategy */
+ /*
+ Index of the first inner table that we intend to handle with this
+ strategy
+ */
+ uint first_firstmatch_table;
+ /*
+ Tables that were not in the join prefix when we've started considering
+ FirstMatch strategy.
+ */
+ table_map first_firstmatch_rtbl;
+ /*
+ Tables that need to be in the prefix before we can calculate the cost
+ of using FirstMatch strategy.
+ */
+ table_map firstmatch_need_tables;
+
+
+/* Duplicate Weedout strategy */
+ /* The first table that the strategy will need to handle */
+ uint first_dupsweedout_table;
+ /*
+ Tables that we will need to have in the prefix to do the weedout step
+ (all inner and all outer that the involved semi-joins are correlated with)
+ */
+ table_map dupsweedout_tables;
+
+/* SJ-Materialization-Scan strategy */
+ /* The last inner table (valid once we're after it) */
+ uint sjm_scan_last_inner;
+ /*
+ Tables that we need to have in the prefix to calculate the correct cost.
+ Basically, we need all inner tables and outer tables mentioned in the
+ semi-join's ON expression so we can correctly account for fanout.
+ */
+ table_map sjm_scan_need_tables;
} POSITION;
@@ -280,6 +553,19 @@ typedef struct st_rollup
} ROLLUP;
+#define SJ_OPT_NONE 0
+#define SJ_OPT_DUPS_WEEDOUT 1
+#define SJ_OPT_LOOSE_SCAN 2
+#define SJ_OPT_FIRST_MATCH 3
+#define SJ_OPT_MATERIALIZE 4
+#define SJ_OPT_MATERIALIZE_SCAN 5
+
+inline bool sj_is_materialize_strategy(uint strategy)
+{
+ return strategy >= SJ_OPT_MATERIALIZE;
+}
+
+
class JOIN :public Sql_alloc
{
JOIN(const JOIN &rhs); /**< not implemented */
@@ -288,9 +574,19 @@ public:
JOIN_TAB *join_tab,**best_ref;
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
- TABLE **table,**all_tables,*sort_by_table;
- uint tables,const_tables;
+ TABLE **table;
+ TABLE **all_tables;
+ /**
+ The table which has an index that allows to produce the requried ordering.
+ A special value of 0x1 means that the ordering will be produced by
+ passing 1st non-const table to filesort(). NULL means no such table exists.
+ */
+ TABLE *sort_by_table;
+ uint tables; /**< Number of tables in the join */
+ uint outer_tables; /**< Number of tables that are not inside semijoin */
+ uint const_tables;
uint send_group_parts;
+ bool group; /**< If query contains GROUP BY clause */
/**
Indicates that grouping will be performed on the result set during
query execution. This field belongs to query execution.
@@ -298,7 +594,7 @@ public:
@see make_group_fields, alloc_group_fields, JOIN::exec
*/
bool sort_and_group;
- bool first_record,full_join,group, no_field_update;
+ bool first_record,full_join, no_field_update;
bool do_send_rows;
/**
TRUE when we want to resume nested loop iterations when
@@ -329,14 +625,47 @@ public:
- on each fetch iteration we add num_rows to fetch to fetch_limit
*/
ha_rows fetch_limit;
- POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
+ /* Finally picked QEP. This is result of join optimization */
+ POSITION best_positions[MAX_TABLES+1];
+
+/******* Join optimization state members start *******/
+ /*
+ pointer - we're doing optimization for a semi-join materialization nest.
+ NULL - otherwise
+ */
+ TABLE_LIST *emb_sjm_nest;
+
+ /* Current join optimization state */
+ POSITION positions[MAX_TABLES+1];
- /* *
+ /*
Bitmap of nested joins embedding the position at the end of the current
partial join (valid only during join optimizer run).
*/
nested_join_map cur_embedding_map;
+
+ /*
+ Bitmap of inner tables of semi-join nests that have a proper subset of
+ their tables in the current join prefix. That is, of those semi-join
+ nests that have their tables both in and outside of the join prefix.
+ */
+ table_map cur_sj_inner_tables;
+
+ /*
+ Bitmap of semi-join inner tables that are in the join prefix and for
+ which there's no provision for how to eliminate semi-join duplicates
+ they produce.
+ */
+ table_map cur_dups_producing_tables;
+ /* We also maintain a stack of join optimization states in * join->positions[] */
+/******* Join optimization state members end *******/
+ Next_select_func first_select;
+ /*
+ The cost of best complete join plan found so far during optimization,
+ after optimization phase - cost of picked join order (not taking into
+ account the changes made by test_if_skip_sort_order()).
+ */
double best_read;
List<Item> *fields;
List<Cached_item> group_fields, group_fields_cache;
@@ -440,6 +769,7 @@ public:
TABLE_LIST *tables_list; ///<hold 'tables' parameter of mysql_select
List<TABLE_LIST> *join_list; ///< list of joined tables in reverse order
COND_EQUAL *cond_equal;
+ COND_EQUAL *having_equal;
SQL_SELECT *select; ///<created in optimisation phase
JOIN_TAB *return_tab; ///<used only for outer joins
Item **ref_pointer_array; ///<used pointer reference for this select
@@ -451,6 +781,13 @@ public:
bool union_part; ///< this subselect is part of union
bool optimized; ///< flag to avoid double optimization in EXPLAIN
+ Array<Item_in_subselect> sj_subselects;
+
+ /* Temporary tables used to weed-out semi-join duplicates */
+ List<TABLE> sj_tmp_tables;
+ /* SJM nests that are executed with SJ-Materialization strategy */
+ List<SJ_MATERIALIZATION_INFO> sjm_info_list;
+
/*
storage for caching buffers allocated during query execution.
These buffers allocations need to be cached as the thread memory pool is
@@ -468,7 +805,7 @@ public:
JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
select_result *result_arg)
- :fields_list(fields_arg)
+ :fields_list(fields_arg), sj_subselects(thd_arg->mem_root, 4)
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
@@ -520,6 +857,7 @@ public:
zero_result_cause= 0;
optimized= 0;
cond_equal= 0;
+ having_equal= 0;
group_optimized_away= 0;
no_rows_in_result_called= 0;
@@ -532,6 +870,7 @@ public:
rollup.state= ROLLUP::STATE_NONE;
no_const_tables= FALSE;
+ first_select= sub_select;
}
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
@@ -544,6 +883,8 @@ public:
int destroy();
void restore_tmp();
bool alloc_func_list();
+ bool flatten_subqueries();
+ bool setup_subquery_materialization();
bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
bool before_group_by, bool recompute= FALSE);
@@ -565,7 +906,6 @@ public:
Item_sum ***func);
int rollup_send_data(uint idx);
int rollup_write_data(uint idx, TABLE *table);
- void remove_subq_pushed_predicates(Item **where);
/**
Release memory and, if possible, the open tables held by this execution
plan (and nested plans). It's used to release some tables before
@@ -593,6 +933,21 @@ public:
{
return (table_map(1) << tables) - 1;
}
+ /*
+ Return the table for which an index scan can be used to satisfy
+ the sort order needed by the ORDER BY/(implicit) GROUP BY clause
+ */
+ JOIN_TAB *get_sort_by_join_tab()
+ {
+ return (need_tmp || !sort_by_table || skip_sort_order ||
+ ((group || tmp_table_param.sum_func_count) && !group_list)) ?
+ NULL : join_tab+const_tables;
+ }
+ bool setup_subquery_caches();
+ bool shrink_join_buffers(JOIN_TAB *jt,
+ ulonglong curr_space,
+ ulonglong needed_space);
+
private:
/**
TRUE if the query contains an aggregate function but has no GROUP
@@ -613,11 +968,6 @@ void TEST_join(JOIN *join);
/* Extern functions in sql_select.cc */
bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag);
-TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
- ORDER *group, bool distinct, bool save_sum_fields,
- ulonglong select_options, ha_rows rows_limit,
- char* alias);
-void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
List<Item> &fields, bool reset_with_sum_func);
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
@@ -727,6 +1077,15 @@ class store_key_field: public store_key
TABLE *table= copy_field.to_field->table;
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
table->write_set);
+
+ /*
+ It looks like the next statement is needed only for a simplified
+ hash function over key values used now in BNLH join.
+ When the implementation of this function will be replaced for a proper
+ full version this statement probably should be removed.
+ */
+ bzero(copy_field.to_ptr,copy_field.to_length);
+
copy_field.do_copy(&copy_field);
dbug_tmp_restore_column_map(table->write_set, old_map);
null_key= to_field->is_null();
@@ -739,12 +1098,17 @@ class store_key_item :public store_key
{
protected:
Item *item;
+ /*
+ Flag that forces usage of save_val() method which save value of the
+ item instead of save_in_field() method which saves result.
+ */
+ bool use_value;
public:
store_key_item(THD *thd, Field *to_field_arg, uchar *ptr,
- uchar *null_ptr_arg, uint length, Item *item_arg)
+ uchar *null_ptr_arg, uint length, Item *item_arg, bool val)
:store_key(thd, to_field_arg, ptr,
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
- &err : (uchar*) 0, length), item(item_arg)
+ &err : (uchar*) 0, length), item(item_arg), use_value(val)
{}
const char *name() const { return "func"; }
@@ -754,7 +1118,20 @@ public:
TABLE *table= to_field->table;
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
table->write_set);
- int res= item->save_in_field(to_field, 1);
+ int res= FALSE;
+
+ /*
+ It looks like the next statement is needed only for a simplified
+ hash function over key values used now in BNLH join.
+ When the implementation of this function will be replaced for a proper
+ full version this statement probably should be removed.
+ */
+ to_field->reset();
+
+ if (use_value)
+ item->save_val(to_field);
+ else
+ res= item->save_in_field(to_field, 1);
/*
Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
we need to check for errors executing it and react accordingly
@@ -778,7 +1155,7 @@ public:
Item *item_arg)
:store_key_item(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
- &err : (uchar*) 0, length, item_arg), inited(0)
+ &err : (uchar*) 0, length, item_arg, FALSE), inited(0)
{
}
const char *name() const { return "const"; }
@@ -812,12 +1189,60 @@ bool error_if_full_join(JOIN *join);
int report_error(TABLE *table, int error);
int safe_index_read(JOIN_TAB *tab);
COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
+int test_if_item_cache_changed(List<Cached_item> &list);
+int join_init_read_record(JOIN_TAB *tab);
void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key);
+inline Item * and_items(Item* cond, Item *item)
+{
+ return (cond? (new Item_cond_and(cond, item)) : item);
+}
+bool choose_plan(JOIN *join,table_map join_tables);
+void get_partial_join_cost(JOIN *join, uint n_tables, double *read_time_arg,
+ double *record_count_arg);
+void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
+ table_map last_remaining_tables,
+ bool first_alt, uint no_jbuf_before,
+ double *outer_rec_count, double *reopt_cost);
+Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
+ bool *inherited_fl);
+bool test_if_ref(COND *root_cond,
+ Item_field *left_item,Item *right_item);
inline bool optimizer_flag(THD *thd, uint flag)
{
return (thd->variables.optimizer_switch & flag);
}
+/* Table elimination entry point function */
void eliminate_tables(JOIN *join);
+/* Index Condition Pushdown entry point function */
+void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok,
+ bool factor_out);
+
+/****************************************************************************
+ Temporary table support for SQL Runtime
+ ***************************************************************************/
+
+#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
+#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
+#define RATIO_TO_PACK_ROWS 2
+#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
+
+TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
+ ORDER *group, bool distinct, bool save_sum_fields,
+ ulonglong select_options, ha_rows rows_limit,
+ char* alias);
+void free_tmp_table(THD *thd, TABLE *entry);
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
+ int error, bool ignore_last_dupp_key_error);
+bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
+ ulonglong options);
+bool open_tmp_table(TABLE *table);
+void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps);
+
+#endif /* SQL_SELECT_INCLUDED */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d8baab6e72c..61f3709476c 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -816,7 +816,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
protocol->store(table_list->schema_table->table_name,
system_charset_info);
else
- protocol->store(table_list->table->alias, system_charset_info);
+ protocol->store(table_list->table->alias.c_ptr(), system_charset_info);
}
if (table_list->view)
@@ -1305,7 +1305,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
else
{
if (lower_case_table_names == 2)
- alias= table->alias;
+ alias= table->alias.c_ptr();
else
{
alias= share->table_name.str;
@@ -1942,8 +1942,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
pthread_mutex_lock(&mysys_var->mutex);
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
#ifndef EMBEDDED_LIBRARY
- thd_info->state_info= (char*) (tmp->locked ? "Locked" :
- tmp->net.reading_or_writing ?
+ thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
(tmp->net.reading_or_writing == 2 ?
"Writing to net" :
thd_info->command == COM_SLEEP ? "" :
@@ -2068,8 +2067,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[5]->store(utime / 1000000, TRUE);
/* STATE */
#ifndef EMBEDDED_LIBRARY
- val= (char*) (tmp->locked ? "Locked" :
- tmp->net.reading_or_writing ?
+ val= (char*) (tmp->net.reading_or_writing ?
(tmp->net.reading_or_writing == 2 ?
"Writing to net" :
tmp->command == COM_SLEEP ? "" :
@@ -2819,9 +2817,10 @@ bool schema_table_store_record(THD *thd, TABLE *table)
int error;
if ((error= table->file->ha_write_row(table->record[0])))
{
- if (create_internal_tmp_table_from_heap(thd, table,
- table->pos_in_table_list->schema_table_param,
- error, 0))
+ TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
+ if (create_internal_tmp_table_from_heap(thd, table, param->start_recinfo,
+ &param->recinfo, error, 0))
+
return 1;
}
return 0;
@@ -5661,7 +5660,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
if (et.load_from_row(thd, event_table))
{
- my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias);
+ my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias.c_ptr());
DBUG_RETURN(1);
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index eafd8502706..b359b2a7168 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -411,7 +411,7 @@ bool String::append(const String &s)
{
if (s.length())
{
- if (realloc(str_length+s.length()))
+ if (realloc_with_extra_if_needed(str_length+s.length()))
return TRUE;
memcpy(Ptr+str_length,s.ptr(),s.length());
str_length+=s.length();
@@ -436,7 +436,7 @@ bool String::append(const char *s,uint32 arg_length)
{
uint32 add_length=arg_length * str_charset->mbmaxlen;
uint dummy_errors;
- if (realloc(str_length+ add_length))
+ if (realloc_with_extra_if_needed(str_length+ add_length))
return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
s, arg_length, &my_charset_latin1,
@@ -447,7 +447,7 @@ bool String::append(const char *s,uint32 arg_length)
/*
For an ASCII compatinble string we can just append.
*/
- if (realloc(str_length+arg_length))
+ if (realloc_with_extra_if_needed(str_length+arg_length))
return TRUE;
memcpy(Ptr+str_length,s,arg_length);
str_length+=arg_length;
@@ -478,14 +478,14 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
{
uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
uint dummy_errors;
- if (realloc(str_length + add_length))
+ if (realloc_with_extra_if_needed(str_length + add_length))
return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
s, arg_length, cs, &dummy_errors);
}
else
{
- if (realloc(str_length + arg_length))
+ if (realloc_with_extra_if_needed(str_length + arg_length))
return TRUE;
memcpy(Ptr + str_length, s, arg_length);
str_length+= arg_length;
@@ -497,7 +497,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{
- if (realloc(str_length+arg_length))
+ if (realloc_with_extra_if_needed(str_length+arg_length))
return TRUE;
if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags))
{
@@ -511,7 +511,7 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags)
bool String::append(IO_CACHE* file, uint32 arg_length)
{
- if (realloc(str_length+arg_length))
+ if (realloc_with_extra_if_needed(str_length+arg_length))
return TRUE;
if (my_b_read(file, (uchar*) Ptr + str_length, arg_length))
{
@@ -527,7 +527,7 @@ bool String::append_with_prefill(const char *s,uint32 arg_length,
{
int t_length= arg_length > full_length ? arg_length : full_length;
- if (realloc(str_length + t_length))
+ if (realloc_with_extra_if_needed(str_length + t_length))
return TRUE;
t_length= full_length - arg_length;
if (t_length > 0)
@@ -636,7 +636,7 @@ bool String::replace(uint32 offset,uint32 arg_length,
{
if (diff)
{
- if (realloc(str_length+(uint32) diff))
+ if (realloc_with_extra_if_needed(str_length+(uint32) diff))
return TRUE;
bmove_upp((uchar*) Ptr+str_length+diff, (uchar*) Ptr+str_length,
str_length-offset-arg_length);
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 0b521eb6f49..5da0d38f24d 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -53,23 +53,24 @@ uint convert_to_printable(char *to, size_t to_len,
class String
{
char *Ptr;
- uint32 str_length,Alloced_length;
+ uint32 str_length,Alloced_length, extra_alloc;
bool alloced;
CHARSET_INFO *str_charset;
public:
String()
{
- Ptr=0; str_length=Alloced_length=0; alloced=0;
+ Ptr=0; str_length=Alloced_length=extra_alloc=0; alloced=0;
str_charset= &my_charset_bin;
}
String(uint32 length_arg)
{
- alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
+ alloced=0; Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg);
str_charset= &my_charset_bin;
}
String(const char *str, CHARSET_INFO *cs)
{
- Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
+ Ptr=(char*) str; str_length= (uint32) strlen(str);
+ Alloced_length= extra_alloc= 0; alloced=0;
str_charset=cs;
}
/*
@@ -79,18 +80,18 @@ public:
*/
String(const char *str,uint32 len, CHARSET_INFO *cs)
{
- Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
+ Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0; alloced=0;
str_charset=cs;
}
String(char *str,uint32 len, CHARSET_INFO *cs)
{
- Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
+ Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0; alloced=0;
str_charset=cs;
}
String(const String &str)
{
Ptr=str.Ptr ; str_length=str.str_length ;
- Alloced_length=str.Alloced_length; alloced=0;
+ Alloced_length=str.Alloced_length; extra_alloc= 0; alloced=0;
str_charset=str.str_charset;
}
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
@@ -110,8 +111,10 @@ public:
inline CHARSET_INFO *charset() const { return str_charset; }
inline uint32 length() const { return str_length;}
inline uint32 alloced_length() const { return Alloced_length;}
+ inline uint32 extra_allocation() const { return extra_alloc;}
inline char& operator [] (uint32 i) const { return Ptr[i]; }
inline void length(uint32 len) { str_length=len ; }
+ inline void extra_allocation(uint32 len) { extra_alloc= len; }
inline bool is_empty() const { return (str_length == 0); }
inline void mark_as_const() { Alloced_length= 0;}
inline const char *ptr() const { return Ptr; }
@@ -140,23 +143,21 @@ public:
{
DBUG_ASSERT(&str != this);
free();
- Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
+ Ptr=(char*) str.ptr()+offset; str_length=arg_length;
if (str.Alloced_length)
Alloced_length=str.Alloced_length-offset;
- else
- Alloced_length=0;
str_charset=str.str_charset;
}
inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
- Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
+ Ptr=(char*) str; str_length=Alloced_length=arg_length;
str_charset=cs;
}
inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
- Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
+ Ptr=(char*) str; str_length=arg_length;
str_charset=cs;
}
bool set_ascii(const char *str, uint32 arg_length);
@@ -207,11 +208,11 @@ public:
if (alloced)
{
alloced=0;
- Alloced_length=0;
my_free(Ptr,MYF(0));
- Ptr=0;
- str_length=0; /* Safety */
}
+ Alloced_length= extra_alloc= 0;
+ Ptr=0;
+ str_length=0; /* Safety */
}
inline bool alloc(uint32 arg_length)
{
@@ -221,9 +222,21 @@ public:
}
bool real_alloc(uint32 arg_length); // Empties old string
bool realloc(uint32 arg_length);
- inline void shrink(uint32 arg_length) // Shrink buffer
+ bool realloc_with_extra(uint32 arg_length)
+ {
+ if (extra_alloc < 4096)
+ extra_alloc= extra_alloc*2+128;
+ return realloc(arg_length + extra_alloc);
+ }
+ bool realloc_with_extra_if_needed(uint32 arg_length)
{
if (arg_length < Alloced_length)
+ return 0;
+ return realloc_with_extra(arg_length);
+ }
+ inline void shrink(uint32 arg_length) // Shrink buffer
+ {
+ if (ALIGN_SIZE(arg_length+1) < Alloced_length)
{
char *new_ptr;
if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
@@ -250,7 +263,6 @@ public:
DBUG_ASSERT(!s.uses_buffer_owned_by(this));
free();
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
- alloced=0;
}
return *this;
}
@@ -266,6 +278,14 @@ public:
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
CHARSET_INFO *csto, uint *errors);
+ void move(String &s)
+ {
+ free();
+ Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
+ extra_alloc= s.extra_alloc;
+ alloced= s.alloced;
+ s.alloced= 0;
+ }
bool append(const String &s);
bool append(const char *s);
bool append(const char *s,uint32 arg_length);
@@ -285,7 +305,7 @@ public:
}
else
{
- if (realloc(str_length+1))
+ if (realloc_with_extra(str_length + 1))
return 1;
Ptr[str_length++]=chr;
}
@@ -296,6 +316,7 @@ public:
friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
+ friend class Field;
uint32 numchars();
int charpos(int i,uint32 offset=0);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index fcf78b4c5fb..7138c82d891 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -24,6 +24,7 @@
#include "sql_trigger.h"
#include "sql_show.h"
#include "debug_sync.h"
+#include "sql_handler.h"
#ifdef __WIN__
#include <io.h>
@@ -2113,7 +2114,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{
if (!foreign_key_error)
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
- wrong_tables.c_ptr());
+ wrong_tables.c_ptr_safe());
else
my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
error= 1;
@@ -6955,7 +6956,7 @@ view_err:
error= 0;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
- table->alias);
+ table->alias.c_ptr());
}
VOID(pthread_mutex_lock(&LOCK_open));
@@ -7023,7 +7024,7 @@ view_err:
error= 0;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
- table->alias);
+ table->alias.c_ptr());
}
if (!error)
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 541fcc155af..5bf9cd1f77e 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -57,14 +57,15 @@ print_where(COND *cond,const char *info, enum_query_type query_type)
{
if (cond)
{
- char buff[256];
+ char buff[1024];
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
+ str.extra_allocation(1024);
cond->print(&str, query_type);
str.append('\0');
DBUG_LOCK_FILE;
(void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info);
- (void) fputs(str.ptr(),DBUG_FILE);
+ (void) fputs(str.c_ptr_safe(),DBUG_FILE);
(void) fputc('\n',DBUG_FILE);
DBUG_UNLOCK_FILE;
}
@@ -156,7 +157,7 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length)
out.append('\0'); // Purify doesn't like c_ptr()
DBUG_LOCK_FILE;
VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE));
- fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr());
+ fprintf(DBUG_FILE,"Sortorder: %s\n",out.c_ptr_safe());
DBUG_UNLOCK_FILE;
DBUG_VOID_RETURN;
}
@@ -191,7 +192,7 @@ TEST_join(JOIN *join)
TABLE *form=tab->table;
char key_map_buff[128];
fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n",
- form->alias,
+ form->alias.c_ptr(),
join_type_str[tab->type],
tab->keys.print(key_map_buff),
tab->ref.key_parts,
@@ -215,7 +216,7 @@ TEST_join(JOIN *join)
if (tab->ref.key_parts)
{
fprintf(DBUG_FILE,
- " refs: %s\n", ref_key_parts[i].ptr());
+ " refs: %s\n", ref_key_parts[i].c_ptr_safe());
}
}
DBUG_UNLOCK_FILE;
@@ -223,6 +224,44 @@ TEST_join(JOIN *join)
}
+#define FT_KEYPART (MAX_REF_PARTS+10)
+
+void print_keyuse(KEYUSE *keyuse)
+{
+ char buff[256];
+ char buf2[64];
+ const char *fieldname;
+ String str(buff,(uint32) sizeof(buff), system_charset_info);
+ str.length(0);
+ keyuse->val->print(&str, QT_ORDINARY);
+ str.append('\0');
+ if (keyuse->keypart == FT_KEYPART)
+ fieldname= "FT_KEYPART";
+ else
+ fieldname= keyuse->table->key_info[keyuse->key].key_part[keyuse->keypart].field->field_name;
+ longlong2str(keyuse->used_tables, buf2, 16, 0);
+ DBUG_LOCK_FILE;
+ fprintf(DBUG_FILE, "KEYUSE: %s.%s=%s optimize: %u used_tables: %s "
+ "ref_table_rows: %lu keypart_map: %0lx\n",
+ keyuse->table->alias.c_ptr(), fieldname, str.ptr(),
+ (uint) keyuse->optimize, buf2, (ulong) keyuse->ref_table_rows,
+ (ulong) keyuse->keypart_map);
+ DBUG_UNLOCK_FILE;
+ //key_part_map keypart_map; --?? there can be several?
+}
+
+
+/* purecov: begin inspected */
+void print_keyuse_array(DYNAMIC_ARRAY *keyuse_array)
+{
+ DBUG_LOCK_FILE;
+ fprintf(DBUG_FILE, "KEYUSE array (%d elements)\n", keyuse_array->elements);
+ DBUG_UNLOCK_FILE;
+ for(uint i=0; i < keyuse_array->elements; i++)
+ print_keyuse((KEYUSE*)dynamic_array_ptr(keyuse_array, i));
+}
+
+
/*
Print the current state during query optimization.
@@ -323,6 +362,27 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
DBUG_UNLOCK_FILE;
}
+
+void print_sjm(SJ_MATERIALIZATION_INFO *sjm)
+{
+ DBUG_LOCK_FILE;
+ fprintf(DBUG_FILE, "\nsemi-join nest{\n");
+ fprintf(DBUG_FILE, " tables { \n");
+ for (uint i= 0;i < sjm->tables; i++)
+ {
+ fprintf(DBUG_FILE, " %s%s\n",
+ sjm->positions[i].table->table->alias.c_ptr(),
+ (i == sjm->tables -1)? "": ",");
+ }
+ fprintf(DBUG_FILE, " }\n");
+ fprintf(DBUG_FILE, " materialize_cost= %g\n",
+ sjm->materialization_cost.total_cost());
+ fprintf(DBUG_FILE, " rows= %g\n", sjm->rows);
+ fprintf(DBUG_FILE, "}\n");
+ DBUG_UNLOCK_FILE;
+}
+/* purecov: end */
+
#endif
typedef struct st_debug_lock
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index e32bedd80a0..8b95a36bc35 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -19,6 +19,7 @@
#include "sp_head.h"
#include "sql_trigger.h"
#include "parse_file.h"
+#include "sql_handler.h"
/*************************************************************************/
@@ -802,7 +803,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
stmt_query->append(stmt_definition.str, stmt_definition.length);
- trg_def->str= stmt_query->c_ptr();
+ trg_def->str= stmt_query->c_ptr_safe();
trg_def->length= stmt_query->length();
/* Create trigger definition file. */
@@ -1039,10 +1040,7 @@ void Table_triggers_list::set_table(TABLE *new_table)
{
trigger_table= new_table;
for (Field **field= new_table->triggers->record1_field ; *field ; field++)
- {
- (*field)->table= (*field)->orig_table= new_table;
- (*field)->table_name= &new_table->alias;
- }
+ (*field)->init(new_table);
}
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index f6754a75284..08125f94b43 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -17,7 +17,7 @@
/**
This class holds all information about triggers of table.
- QQ: Will it be merged into TABLE in the future ?
+ TODO: Will it be merged into TABLE in the future ?
*/
class Table_triggers_list: public Sql_alloc
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 2cedce497b6..a94ad9f3b4b 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -51,21 +51,23 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
bool select_union::send_data(List<Item> &values)
{
- int error= 0;
if (unit->offset_limit_cnt)
{ // using limit offset,count
unit->offset_limit_cnt--;
return 0;
}
- fill_record(thd, table->field, values, 1);
+ fill_record(thd, table->field, values, TRUE, FALSE);
if (thd->is_error())
return 1;
- if ((error= table->file->ha_write_row(table->record[0])))
+ if ((write_err= table->file->ha_write_row(table->record[0])))
{
/* create_internal_tmp_table_from_heap will generate error if needed */
- if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
- create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1))
+ if (table->file->is_fatal_error(write_err, HA_CHECK_DUP) &&
+ create_internal_tmp_table_from_heap(thd, table,
+ tmp_table_param.start_recinfo,
+ &tmp_table_param.recinfo,
+ write_err, 1))
return 1;
}
return 0;
@@ -100,6 +102,8 @@ bool select_union::flush()
is_union_distinct if set, the temporary table will eliminate
duplicates on insert
options create options
+ table_alias name of the temporary table
+ bit_fields_as_long convert bit fields to ulonglong
DESCRIPTION
Create a temporary table that is used to store the result of a UNION,
@@ -113,11 +117,13 @@ bool select_union::flush()
bool
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
bool is_union_distinct, ulonglong options,
- const char *alias)
+ const char *alias,
+ bool bit_fields_as_long)
{
DBUG_ASSERT(table == 0);
tmp_table_param.init();
tmp_table_param.field_count= column_types->elements;
+ tmp_table_param.bit_fields_as_long= bit_fields_as_long;
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, is_union_distinct, 1,
@@ -129,6 +135,22 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
}
+/**
+ Reset and empty the temporary table that stores the materialized query result.
+
+ @note The cleanup performed here is exactly the same as for the two temp
+ tables of JOIN - exec_tmp_table_[1 | 2].
+*/
+
+void select_union::cleanup()
+{
+ table->file->extra(HA_EXTRA_RESET_STATE);
+ table->file->ha_delete_all_rows();
+ free_io_cache(table);
+ filesort_free_buffers(table,0);
+}
+
+
/*
initialization procedures before fake_select_lex preparation()
@@ -366,7 +388,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
create_options= create_options | TMP_TABLE_FORCE_MYISAM;
if (union_result->create_result_table(thd, &types, test(union_distinct),
- create_options, ""))
+ create_options, "", FALSE))
goto err;
bzero((char*) &result_table_list, sizeof(result_table_list));
result_table_list.db= (char*) "";
@@ -730,8 +752,8 @@ void st_select_lex_unit::reinit_exec_mechanism()
TRUE - error
*/
-bool st_select_lex_unit::change_result(select_subselect *new_result,
- select_subselect *old_result)
+bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
+ select_result_interceptor *old_result)
{
bool res= FALSE;
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 97ad7d88573..6a4027318d5 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1617,7 +1617,8 @@ loop_end:
do
{
Field_string *field= new Field_string(tbl->file->ref_length, 0,
- tbl->alias, &my_charset_bin);
+ tbl->alias.c_ptr(),
+ &my_charset_bin);
if (!field)
DBUG_RETURN(1);
field->init(tbl);
@@ -1828,7 +1829,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
/* Store regular updated fields in the row. */
fill_record(thd,
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
- *values_for_table[offset], 1);
+ *values_for_table[offset], TRUE, FALSE);
/* Write row, ignoring duplicated updates to a row */
error= tmp_table->file->ha_write_row(tmp_table->record[0]);
@@ -1836,7 +1837,9 @@ bool multi_update::send_data(List<Item> &not_used_values)
{
if (error &&
create_internal_tmp_table_from_heap(thd, tmp_table,
- tmp_table_param + offset, error, 1))
+ tmp_table_param[offset].start_recinfo,
+ &tmp_table_param[offset].recinfo,
+ error, 1))
{
do_update= 0;
DBUG_RETURN(1); // Not a table_is_full error
@@ -2080,8 +2083,8 @@ int multi_update::do_updates()
err:
{
thd->fatal_error();
- prepare_record_for_error_message(local_error, table);
- table->file->print_error(local_error,MYF(0));
+ prepare_record_for_error_message(local_error, err_table);
+ err_table->file->print_error(local_error,MYF(0));
}
err2:
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 204100f6034..8b8b7f5c90e 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -848,7 +848,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
thd->variables.sql_mode|= sql_mode;
}
- DBUG_PRINT("info", ("View: %s", view_query.ptr()));
+ DBUG_PRINT("info", ("View: %s", view_query.c_ptr_safe()));
/* fill structure */
view->source= thd->lex->create_view_select;
@@ -1675,7 +1675,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
}
if (non_existant_views.length())
{
- my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr());
+ my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr_safe());
}
something_wrong= error || wrong_object_name || non_existant_views.length();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 884fbe9ed76..3ed25f2e78f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -13121,7 +13121,7 @@ column_list_id:
while ((point=iter++))
{
if (!my_strcasecmp(system_charset_info,
- point->column.ptr(), new_str->ptr()))
+ point->column.c_ptr(), new_str->c_ptr()))
break;
}
lex->grant_tot_col|= lex->which_columns;
diff --git a/sql/structs.h b/sql/structs.h
index 64e69fca0d0..fbbafafe3ea 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -53,7 +53,8 @@ typedef struct st_key_part_info { /* Info about a key part */
Field *field;
uint offset; /* offset in record (from 0) */
uint null_offset; /* Offset to null_bit in record */
- uint16 length; /* Length of keypart value in bytes */
+ /* Length of key part in bytes, excluding NULL flag and length bytes */
+ uint16 length;
/*
Number of bytes required to store the keypart value. This may be
different from the "length" field as it also counts
@@ -126,6 +127,21 @@ class SQL_SELECT;
class THD;
class handler;
struct st_join_table;
+class Copy_field;
+
+/**
+ A context for reading through a single table using a chosen access method:
+ index read, scan, etc, use of cache, etc.
+
+ Use by:
+ READ_RECORD read_record;
+ init_read_record(&read_record, ...);
+ while (read_record.read_record())
+ {
+ ...
+ }
+ end_read_record();
+*/
void rr_unlock_row(st_join_table *tab);
@@ -149,6 +165,12 @@ struct READ_RECORD { /* Parameter to read_record */
uchar *cache,*cache_pos,*cache_end,*read_positions;
IO_CACHE *io_cache;
bool print_error, ignore_not_found_rows;
+ /*
+ SJ-Materialization runtime may need to read fields from the materialized
+ table and unpack them into original table fields:
+ */
+ Copy_field *copy_field;
+ Copy_field *copy_field_end;
};
diff --git a/sql/table.cc b/sql/table.cc
index 5f448e48d80..9bb2b58fcb3 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -21,6 +21,8 @@
#include "create_options.h"
#include <m_ctype.h>
#include "my_md5.h"
+#include "my_bit.h"
+#include "sql_select.h"
/* INFORMATION_SCHEMA name */
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
@@ -1576,21 +1578,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->table_name.str,
share->table_name.str);
share->crashed= 1; // Marker for CHECK TABLE
- goto to_be_deleted;
+ continue;
}
#endif
key_part->key_part_flag|= HA_PART_KEY_SEG;
}
-
- to_be_deleted:
-
- /*
- If the field can be NULL, don't optimize away the test
- key_part_column = expression from the WHERE clause
- as we need to test for NULL = NULL.
- */
- if (field->real_maybe_null())
- key_part->key_part_flag|= HA_NULL_PART;
/*
Sometimes we can compare key parts for equality with memcmp.
But not always.
@@ -2103,7 +2095,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
- if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
+ if (outparam->alias.copy(alias, strlen(alias), table_alias_charset))
goto err;
outparam->quick_keys.init();
outparam->covering_keys.init();
@@ -2437,7 +2429,7 @@ partititon_err:
outparam->db_stat=0;
thd->lex->view_prepare_mode= save_view_prepare_mode;
free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root
- my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
+ outparam->alias.free();
DBUG_RETURN (error);
}
@@ -2463,8 +2455,7 @@ int closefrm(register TABLE *table, bool free_share)
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
error=table->file->close();
}
- my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
- table->alias= 0;
+ table->alias.free();
if (table->expr_arena)
table->expr_arena->free_items();
if (table->field)
@@ -2941,7 +2932,7 @@ File create_frm(THD *thd, const char *name, const char *db,
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
- /* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */
+ /* Fix this when we have new .frm files; Current limit is 4G rows (TODO) */
if (create_info->max_rows > UINT_MAX32)
create_info->max_rows= UINT_MAX32;
if (create_info->min_rows > UINT_MAX32)
@@ -3301,7 +3292,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
const TABLE_FIELD_TYPE *field_def= table_def->field;
DBUG_ENTER("table_check_intact");
DBUG_PRINT("info",("table: %s expected_count: %d",
- table->alias, table_def->count));
+ table->alias.c_ptr(), table_def->count));
/* Whether the table definition has already been validated. */
if (table->s->table_field_def_cache == table_def)
@@ -3316,14 +3307,15 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
{
report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE,
ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
- table->alias, table_def->count, table->s->fields,
+ table->alias.c_ptr(), table_def->count, table->s->fields,
table->s->mysql_version, MYSQL_VERSION_ID);
DBUG_RETURN(TRUE);
}
else if (MYSQL_VERSION_ID == table->s->mysql_version)
{
report_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED,
- ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
+ ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED),
+ table->alias.c_ptr(),
table_def->count, table->s->fields);
DBUG_RETURN(TRUE);
}
@@ -3335,11 +3327,13 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
is backward compatible.
*/
}
- char buffer[STRING_BUFFER_USUAL_SIZE];
+ char buffer[1024];
for (i=0 ; i < table_def->count; i++, field_def++)
{
String sql_type(buffer, sizeof(buffer), system_charset_info);
sql_type.length(0);
+ /* Allocate min 256 characters at once */
+ sql_type.extra_allocation(256);
if (i < table->s->fields)
{
Field *field= table->field[i];
@@ -3354,7 +3348,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
*/
report_error(0, "Incorrect definition of table %s.%s: "
"expected column '%s' at position %d, found '%s'.",
- table->s->db.str, table->alias, field_def->name.str, i,
+ table->s->db.str, table->alias.c_ptr(),
+ field_def->name.str, i,
field->field_name);
}
field->sql_type(sql_type);
@@ -3380,7 +3375,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
{
report_error(0, "Incorrect definition of table %s.%s: "
"expected column '%s' at position %d to have type "
- "%s, found type %s.", table->s->db.str, table->alias,
+ "%s, found type %s.", table->s->db.str,
+ table->alias.c_ptr(),
field_def->name.str, i, field_def->type.str,
sql_type.c_ptr_safe());
error= TRUE;
@@ -3390,7 +3386,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
report_error(0, "Incorrect definition of table %s.%s: "
"expected the type of column '%s' at position %d "
"to have character set '%s' but the type has no "
- "character set.", table->s->db.str, table->alias,
+ "character set.", table->s->db.str,
+ table->alias.c_ptr(),
field_def->name.str, i, field_def->cset.str);
error= TRUE;
}
@@ -3400,7 +3397,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
report_error(0, "Incorrect definition of table %s.%s: "
"expected the type of column '%s' at position %d "
"to have character set '%s' but found "
- "character set '%s'.", table->s->db.str, table->alias,
+ "character set '%s'.", table->s->db.str,
+ table->alias.c_ptr(),
field_def->name.str, i, field_def->cset.str,
field->charset()->csname);
error= TRUE;
@@ -3411,7 +3409,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
report_error(0, "Incorrect definition of table %s.%s: "
"expected column '%s' at position %d to have type %s "
" but the column is not found.",
- table->s->db.str, table->alias,
+ table->s->db.str, table->alias.c_ptr(),
field_def->name.str, i, field_def->type.str);
error= TRUE;
}
@@ -5182,6 +5180,132 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl)
file->column_bitmaps_signal();
}
+
+/**
+ Allocate space for keys
+
+ @param key_count number of keys to allocate.
+
+ @details
+ Allocates space enough to fit 'key_count' keys for this table.
+
+ @return FALSE space was successfully allocated.
+ @return TRUE an error occur.
+*/
+
+bool TABLE::alloc_keys(uint key_count)
+{
+ DBUG_ASSERT(!s->keys);
+ key_info= s->key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*key_count);
+ max_keys= key_count;
+ return !(key_info);
+}
+
+
+/**
+ Add a key to a temporary table
+
+ @param key the number of the key
+ @param key_parts number of components of the key
+ @param next_field_no the call-back function that returns the number of
+ the field used as the next component of the key
+ @param arg the argument for the above function
+ @param unique Is it unique index
+
+ @details
+ The function adds a new key to the table that is assumed to be
+ temprary table. The call-back function must at each call must return
+ the number of the field that used as next component of this key
+
+ @return FALSE is a success
+ @return TRUE if a failure
+*/
+
+bool TABLE::add_tmp_key(uint key, uint key_parts,
+ uint (*next_field_no) (uchar *), uchar *arg,
+ bool unique)
+{
+ DBUG_ASSERT(key < max_keys);
+
+ char buf[NAME_CHAR_LEN];
+ KEY* keyinfo;
+ Field **reg_field;
+ uint i;
+ bool key_start= TRUE;
+ KEY_PART_INFO* key_part_info=
+ (KEY_PART_INFO*) alloc_root(&mem_root, sizeof(KEY_PART_INFO)*key_parts);
+ if (!key_part_info)
+ return TRUE;
+ keyinfo= key_info + key;
+ keyinfo->key_part= key_part_info;
+ keyinfo->usable_key_parts= keyinfo->key_parts = key_parts;
+ keyinfo->key_length=0;
+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
+ keyinfo->flags= HA_GENERATED_KEY;
+ if (unique)
+ keyinfo->flags|= HA_NOSAME;
+ sprintf(buf, "key%i", key);
+ if (!(keyinfo->name= strdup_root(&mem_root, buf)))
+ return TRUE;
+ keyinfo->rec_per_key= (ulong*) alloc_root(&mem_root,
+ sizeof(ulong)*key_parts);
+ if (!keyinfo->rec_per_key)
+ return TRUE;
+ bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
+ for (i= 0; i < key_parts; i++)
+ {
+ reg_field= field + next_field_no(arg);
+ if (key_start)
+ (*reg_field)->key_start.set_bit(key);
+ key_start= FALSE;
+ (*reg_field)->part_of_key.set_bit(key);
+ (*reg_field)->flags|= PART_KEY_FLAG;
+ key_part_info->null_bit= (*reg_field)->null_bit;
+ key_part_info->null_offset= (uint) ((*reg_field)->null_ptr -
+ (uchar*) record[0]);
+ key_part_info->field= *reg_field;
+ key_part_info->offset= (*reg_field)->offset(record[0]);
+ key_part_info->length= (uint16) (*reg_field)->pack_length();
+ keyinfo->key_length+= key_part_info->length;
+ key_part_info->key_part_flag= 0;
+ /* 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.
+ This should be factored out, e.g. as a method of Field.
+ In addition it is not clear if any of the Field::*_length
+ methods is supposed to compute the same length. If so, it
+ might be reused.
+ */
+ key_part_info->store_length= key_part_info->length;
+
+ if ((*reg_field)->real_maybe_null())
+ {
+ key_part_info->store_length+= HA_KEY_NULL_LENGTH;
+ keyinfo->key_length+= HA_KEY_NULL_LENGTH;
+ if (unique)
+ keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
+ }
+ if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
+ (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
+ {
+ key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
+ keyinfo->key_length+= HA_KEY_BLOB_LENGTH; // ???
+ }
+
+ key_part_info->type= (uint8) (*reg_field)->key_type();
+ key_part_info->key_type =
+ ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
+ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
+ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
+ 0 : FIELDFLAG_BINARY;
+ key_part_info++;
+ }
+ set_if_bigger(s->max_key_length, keyinfo->key_length);
+ s->keys++;
+ return FALSE;
+}
+
+
/**
@brief Check if this is part of a MERGE table with attached children.
diff --git a/sql/table.h b/sql/table.h
index f2d55929ceb..7688d289f81 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -721,7 +721,7 @@ struct st_table {
Table_triggers_list *triggers;
TABLE_LIST *pos_in_table_list;/* Element referring to this table */
ORDER *group;
- const char *alias; /* alias or table name */
+ String alias; /* alias or table name */
uchar *null_flags;
my_bitmap_map *bitmap_init_value;
MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set;
@@ -790,6 +790,7 @@ struct st_table {
uint temp_pool_slot; /* Used by intern temp tables */
uint status; /* What's in record[0] */
uint db_stat; /* mode of file as in handler.h */
+ uint max_keys; /* Size of allocated key_info array. */
/* number of select if it is derived table */
uint derived_select_number;
int current_lock; /* Type of lock on table */
@@ -950,6 +951,10 @@ struct st_table {
*/
inline bool needs_reopen_or_name_lock()
{ return s->version != refresh_version; }
+ bool alloc_keys(uint key_count);
+ bool add_tmp_key(uint key, uint key_parts,
+ uint (*next_field_no) (uchar *), uchar *arg,
+ bool unique);
bool is_children_attached(void);
inline void enable_keyread()
{
@@ -1171,6 +1176,11 @@ public:
};
+class SJ_MATERIALIZATION_INFO;
+class Index_hint;
+class Item_in_subselect;
+
+
/*
Table reference in the FROM clause.
@@ -1233,6 +1243,20 @@ struct TABLE_LIST
char *db, *alias, *table_name, *schema_table_name;
char *option; /* Used by cache index */
Item *on_expr; /* Used with outer join */
+
+ Item *sj_on_expr;
+ /*
+ (Valid only for semi-join nests) Bitmap of tables that are within the
+ semi-join (this is different from bitmap of all nest's children because
+ tables that were pulled out of the semi-join nest remain listed as
+ nest's children).
+ */
+ table_map sj_inner_tables;
+ /* Number of IN-compared expressions */
+ uint sj_in_exprs;
+ Item_in_subselect *sj_subq_pred;
+ SJ_MATERIALIZATION_INFO *sj_mat_info;
+
/*
The structure of ON expression presented in the member above
can be changed during certain optimizations. This member
@@ -1773,6 +1797,14 @@ typedef struct st_nested_join
*/
uint n_tables;
nested_join_map nj_map; /* Bit used to identify this nested join*/
+ /*
+ (Valid only for semi-join nests) Bitmap of tables outside the semi-join
+ that are used within the semi-join's ON condition.
+ */
+ table_map sj_depends_on;
+ /* Outer non-trivially correlated tables */
+ table_map sj_corr_tables;
+ List<Item> sj_outer_expr_list;
/**
True if this join nest node is completely covered by the query execution
plan. This means two things.
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 3d1ea9243b9..561b1068097 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -423,7 +423,7 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
if (end <= begin ||
merge_buffer_size < (ulong) (key_length * (end - begin + 1)) ||
init_queue(&queue, (uint) (end - begin), offsetof(BUFFPEK, key), 0,
- buffpek_compare, &compare_context))
+ buffpek_compare, &compare_context, 0, 0))
return 1;
/* we need space for one key when a piece of merge buffer is re-read */
merge_buffer_size-= key_length;
@@ -468,7 +468,7 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
*/
top->key+= key_length;
if (--top->mem_count)
- queue_replaced(&queue);
+ queue_replace_top(&queue);
else /* next piece should be read */
{
/* save old_key not to overwrite it in read_to_buffer */
@@ -478,14 +478,14 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
if (bytes_read == (uint) (-1))
goto end;
else if (bytes_read > 0) /* top->key, top->mem_count are reset */
- queue_replaced(&queue); /* in read_to_buffer */
+ queue_replace_top(&queue); /* in read_to_buffer */
else
{
/*
Tree for old 'top' element is empty: remove it from the queue and
give all its memory to the nearest tree.
*/
- queue_remove(&queue, 0);
+ queue_remove_top(&queue);
reuse_freed_buff(&queue, top, key_length);
}
}
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index 2749034cba2..434423b78b3 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -1453,7 +1453,8 @@ static void fill_server(MEM_ROOT *mem_root, FEDERATEDX_SERVER *server,
key.q_append('\0');
server->password= (const char *) (intptr) key.length();
key.append(password);
-
+ key.c_ptr_safe(); // Ensure we have end \0
+
server->key_length= key.length();
server->key= (uchar *) memdup_root(mem_root, key.ptr(), key.length()+1);
@@ -1583,7 +1584,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table)
tmp_share.table_name_length, ident_quote_char);
if (!(share= (FEDERATEDX_SHARE *) memdup_root(&mem_root, (char*)&tmp_share, sizeof(*share))) ||
- !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length() + 1)))
+ !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length())))
goto error;
share->mem_root= mem_root;
@@ -3435,11 +3436,13 @@ bool ha_federatedx::get_error_message(int error, String* buf)
buf->qs_append(remote_error_number);
buf->append(STRING_WITH_LEN(": "));
buf->append(remote_error_buf);
+ /* Ensure string ends with \0 */
+ (void) buf->c_ptr_safe();
remote_error_number= 0;
remote_error_buf[0]= '\0';
}
- DBUG_PRINT("exit", ("message: %s", buf->ptr()));
+ DBUG_PRINT("exit", ("message: %s", buf->c_ptr_safe()));
DBUG_RETURN(FALSE);
}
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 42437a22614..2d2c23a2ed6 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -654,7 +654,8 @@ int ha_heap::create(const char *name, TABLE *table_arg,
seg->type != HA_KEYTYPE_VARTEXT1 &&
seg->type != HA_KEYTYPE_VARTEXT2 &&
seg->type != HA_KEYTYPE_VARBINARY1 &&
- seg->type != HA_KEYTYPE_VARBINARY2)
+ seg->type != HA_KEYTYPE_VARBINARY2 &&
+ seg->type != HA_KEYTYPE_BIT)
seg->type= HA_KEYTYPE_BINARY;
}
seg->start= (uint) key_part->offset;
@@ -686,6 +687,18 @@ int ha_heap::create(const char *name, TABLE *table_arg,
auto_key= key+ 1;
auto_key_type= field->key_type();
}
+ if (seg->type == HA_KEYTYPE_BIT)
+ {
+ seg->bit_length= ((Field_bit *) field)->bit_len;
+ seg->bit_start= ((Field_bit *) field)->bit_ofs;
+ seg->bit_pos= (uint) (((Field_bit *) field)->bit_ptr -
+ (uchar*) table_arg->record[0]);
+ }
+ else
+ {
+ seg->bit_length= seg->bit_start= 0;
+ seg->bit_pos= 0;
+ }
}
}
mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index bc8183bf777..2036bd7166f 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -104,6 +104,14 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
*/
keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
break;
+ case HA_KEYTYPE_BIT:
+ /*
+ The odd bits which stored separately (if they are present
+ (bit_pos, bit_length)) are already present in seg[j].length as
+ additional byte.
+ See field.h, function key_length()
+ */
+ break;
default:
break;
}
diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c
index aaaa0fe833f..fb9ea44a424 100644
--- a/storage/heap/hp_hash.c
+++ b/storage/heap/hp_hash.c
@@ -349,6 +349,15 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
}
else
{
+ if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
+ {
+ uchar bits= get_rec_bits(rec + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) bits))+ (nr << 8);
+ nr2+=3;
+ end--;
+ }
+
for (; pos < end ; pos++)
{
nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
@@ -465,6 +474,14 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
else
{
uchar *end= pos+seg->length;
+ if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
+ {
+ uchar bits= get_rec_bits(rec + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ nr *=16777619;
+ nr ^=(uint) bits;
+ end--;
+ }
for ( ; pos < end ; pos++)
{
nr *=16777619;
@@ -577,7 +594,18 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2,
}
else
{
- if (bcmp(rec1+seg->start,rec2+seg->start,seg->length))
+ uint dec= 0;
+ if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
+ {
+ uchar bits1= get_rec_bits(rec1 + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ uchar bits2= get_rec_bits(rec2 + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ if (bits1 != bits2)
+ return 1;
+ dec= 1;
+ }
+ if (bcmp(rec1 + seg->start, rec2 + seg->start, seg->length - dec))
return 1;
}
}
@@ -660,7 +688,18 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
}
else
{
- if (bcmp(rec+seg->start,key,seg->length))
+ uint dec= 0;
+ if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
+ {
+ uchar bits= get_rec_bits(rec + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ if (bits != (*key))
+ return 1;
+ dec= 1;
+ key++;
+ }
+
+ if (bcmp(rec + seg->start, key, seg->length - dec))
return 1;
}
}
@@ -689,6 +728,12 @@ void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
}
if (seg->type == HA_KEYTYPE_VARTEXT1)
char_length+= seg->bit_start; /* Copy also length */
+ else if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
+ {
+ *key++= get_rec_bits(rec + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ char_length--;
+ }
memcpy(key,rec+seg->start,(size_t) char_length);
key+= char_length;
}
@@ -720,7 +765,8 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
{
uint length= seg->length;
uchar *pos= (uchar*) rec + seg->start;
-
+ DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT);
+
#ifdef HAVE_ISNAN
if (seg->type == HA_KEYTYPE_FLOAT)
{
@@ -784,6 +830,12 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
seg->length - char_length, ' ');
}
+ if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
+ {
+ *key++= get_rec_bits(rec + seg->bit_pos,
+ seg->bit_start, seg->bit_length);
+ char_length--;
+ }
memcpy(key, rec + seg->start, (size_t) char_length);
key+= seg->length;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 4c52326a58a..b2af257273b 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6521,6 +6521,7 @@ ha_innobase::info_low(
}
stats.check_time = 0;
+ stats.mrr_length_per_rec= ref_length + 8; // 8 = max(sizeof(void *));
if (stats.records == 0) {
stats.mean_rec_length = 0;
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 9715cb54d2c..116ee12e76f 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -7684,6 +7684,8 @@ ha_innobase::info_low(
}
stats.check_time = 0;
+ stats.mrr_length_per_rec= ref_length + 8; // 8 = max(sizeof(void *));
+
if (stats.records == 0) {
stats.mean_rec_length = 0;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index a22b9e995c7..6f01d1e9b5e 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1036,6 +1036,16 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
int_table_flags |= HA_HAS_NEW_CHECKSUM;
+ /*
+ For static size rows, tell MariaDB that we will access all bytes
+ in the record when writing it. This signals MariaDB to initalize
+ the full row to ensure we don't get any errors from valgrind and
+ that all bytes in the row is properly reset.
+ */
+ if (file->s->data_file_type == STATIC_RECORD &&
+ (file->s->has_varchar_fields | file->s->has_null_fields))
+ int_table_flags|= HA_RECORD_MUST_BE_CLEAN_ON_WRITE;
+
for (i= 0; i < table->s->keys; i++)
{
plugin_ref parser= table->key_info[i].parser;
@@ -1052,6 +1062,8 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
int ha_maria::close(void)
{
MARIA_HA *tmp= file;
+ if (!tmp)
+ return 0;
file= 0;
return maria_close(tmp);
}
@@ -1091,7 +1103,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
param.thd= thd;
param.op_name= "check";
param.db_name= table->s->db.str;
- param.table_name= table->alias;
+ param.table_name= table->alias.c_ptr();
param.testflag= check_opt->flags | T_CHECK | T_SILENT;
param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
@@ -1190,7 +1202,7 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
param.thd= thd;
param.op_name= "analyze";
param.db_name= table->s->db.str;
- param.table_name= table->alias;
+ param.table_name= table->alias.c_ptr();
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
param.using_global_keycache= 1;
@@ -1485,7 +1497,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
_ma_copy_nontrans_state_information(file);
param->db_name= table->s->db.str;
- param->table_name= table->alias;
+ param->table_name= table->alias.c_ptr();
param->tmpfile_createflag= O_RDWR | O_TRUNC;
param->using_global_keycache= 1;
param->thd= thd;
@@ -2141,6 +2153,20 @@ int ha_maria::delete_row(const uchar * buf)
return maria_delete(file, buf);
}
+C_MODE_START
+
+ICP_RESULT index_cond_func_maria(void *arg)
+{
+ ha_maria *h= (ha_maria*)arg;
+ if (h->end_range)
+ {
+ if (h->compare_key2(h->end_range) > 0)
+ return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
+ }
+ return h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH;
+}
+
+C_MODE_END
int ha_maria::index_read_map(uchar * buf, const uchar * key,
key_part_map keypart_map,
@@ -2230,6 +2256,25 @@ int ha_maria::index_next_same(uchar * buf,
}
+int ha_maria::index_init(uint idx, bool sorted)
+{
+ active_index=idx;
+ if (pushed_idx_cond_keyno == idx)
+ ma_set_index_cond_func(file, index_cond_func_maria, this);
+ return 0;
+}
+
+
+int ha_maria::index_end()
+{
+ active_index=MAX_KEY;
+ ma_set_index_cond_func(file, NULL, 0);
+ in_range_check_pushed_down= FALSE;
+ ds_mrr.dsmrr_close();
+ return 0;
+}
+
+
int ha_maria::rnd_init(bool scan)
{
if (scan)
@@ -2240,6 +2285,7 @@ int ha_maria::rnd_init(bool scan)
int ha_maria::rnd_end()
{
+ ds_mrr.dsmrr_close();
/* Safe to call even if we don't have started a scan */
maria_scan_end(file);
return 0;
@@ -2312,6 +2358,7 @@ int ha_maria::info(uint flag, my_bool lock_table_share)
ref_length= maria_info.reflength;
share->db_options_in_use= maria_info.options;
stats.block_size= maria_block_size;
+ stats.mrr_length_per_rec= maria_info.reflength + 8; // 8 = max(sizeof(void *))
/* Update share */
if (lock_table_share)
@@ -2393,6 +2440,10 @@ int ha_maria::extra(enum ha_extra_function operation)
int ha_maria::reset(void)
{
+ pushed_idx_cond= NULL;
+ pushed_idx_cond_keyno= MAX_KEY;
+ ma_set_index_cond_func(file, NULL, 0);
+ ds_mrr.dsmrr_close();
if (file->trn)
{
/* Next statement is a new statement. Ensure it's logged */
@@ -3554,6 +3605,64 @@ static struct st_mysql_show_var aria_status_variables[]= {
{NullS, NullS, SHOW_LONG}
};
+/****************************************************************************
+ * Maria MRR implementation: use DS-MRR
+ ***************************************************************************/
+
+int ha_maria::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf)
+{
+ return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf);
+}
+
+int ha_maria::multi_range_read_next(char **range_info)
+{
+ return ds_mrr.dsmrr_next(range_info);
+}
+
+ha_rows ha_maria::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)
+{
+ /*
+ This call is here because there is no location where this->table would
+ already be known.
+ TODO: consider moving it into some per-query initialization call.
+ */
+ ds_mrr.init(this, table);
+ return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
+ flags, cost);
+}
+
+ha_rows ha_maria::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost)
+{
+ ds_mrr.init(this, table);
+ return ds_mrr.dsmrr_info(keyno, n_ranges, keys, key_parts, bufsz, flags, cost);
+}
+
+/* MyISAM MRR implementation ends */
+
+
+/* Index condition pushdown implementation*/
+
+
+Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
+{
+ pushed_idx_cond_keyno= keyno_arg;
+ pushed_idx_cond= idx_cond_arg;
+ in_range_check_pushed_down= TRUE;
+ if (active_index == pushed_idx_cond_keyno)
+ ma_set_index_cond_func(file, index_cond_func_maria, this);
+ 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 39307e5efdd..5e7b068d01c 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -13,6 +13,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#ifndef HA_MARIA_INCLUDED
+#define HA_MARIA_INCLUDED
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
@@ -22,6 +24,16 @@
#include <maria.h>
+#define HA_RECOVER_NONE 0 /* No automatic recover */
+#define HA_RECOVER_DEFAULT 1 /* Automatic recover active */
+#define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */
+#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */
+#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */
+
+C_MODE_START
+ICP_RESULT index_cond_func_maria(void *arg);
+C_MODE_END
+
extern ulong maria_sort_buffer_size;
extern TYPELIB maria_recover_typelib;
extern ulong maria_recover_options;
@@ -56,7 +68,7 @@ public:
{
return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
- HA_READ_ORDER | HA_KEYREAD_ONLY);
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
}
uint max_supported_keys() const
{ return MARIA_MAX_KEY; }
@@ -98,6 +110,8 @@ public:
key->charset(), table->record[0]);
}
int ft_read(uchar * buf);
+ int index_init(uint idx, bool sorted);
+ int index_end();
int rnd_init(bool scan);
int rnd_end(void);
int rnd_next(uchar * buf);
@@ -159,4 +173,25 @@ public:
return file;
}
static int implicit_commit(THD *thd, bool new_trn);
+ /**
+ * 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(char **range_info);
+ 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);
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+
+ /* Index condition pushdown implementation */
+ Item *idx_cond_push(uint keyno, Item* idx_cond);
+private:
+ DsMrr_impl ds_mrr;
+ friend ICP_RESULT index_cond_func_maria(void *arg);
};
+
+#endif /* HA_MARIA_INCLUDED */
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index e436a51248a..d39abc1a68e 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -480,6 +480,14 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
} /* maria_extra */
+void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func,
+ void *func_arg)
+{
+ info->index_cond_func= func;
+ info->index_cond_func_arg= func_arg;
+}
+
+
/*
Start/Stop Inserting Duplicates Into a Table, WL#1648.
*/
@@ -626,3 +634,4 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
maria_mark_crashed(info);
return 1;
}
+
diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c
index 40b0623adb1..1b153f1a76f 100644
--- a/storage/maria/ma_ft_boolean_search.c
+++ b/storage/maria/ma_ft_boolean_search.c
@@ -473,14 +473,15 @@ static void _ftb_init_index_search(FT_INFO *ftb)
int i;
FTB_WORD *ftbw;
- if ((ftb->state != READY && ftb->state !=INDEX_DONE) ||
- ftb->keynr == NO_SUCH_KEY)
+ if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
- for (i=ftb->queue.elements; i; i--)
+ for (i= queue_last_element(&ftb->queue);
+ (int) i >= (int) queue_first_element(&ftb->queue);
+ i--)
{
- ftbw=(FTB_WORD *)(ftb->queue.root[i]);
+ ftbw=(FTB_WORD *)(queue_element(&ftb->queue, i));
if (ftbw->flags & FTB_FLAG_TRUNC)
{
@@ -585,7 +586,7 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr,
sizeof(void *))))
goto err;
reinit_queue(&ftb->queue, ftb->queue.max_elements, 0, 0,
- (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0);
+ (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0, 0, 0);
for (ftbw= ftb->last_word; ftbw; ftbw= ftbw->prev)
queue_insert(&ftb->queue, (uchar *)ftbw);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
@@ -828,7 +829,7 @@ int maria_ft_boolean_read_next(FT_INFO *ftb, char *record)
/* update queue */
_ft2_search(ftb, ftbw, 0);
- queue_replaced(& ftb->queue);
+ queue_replace_top(&ftb->queue);
}
ftbe=ftb->root;
diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c
index 927f34f8b72..3bb7defcaaf 100644
--- a/storage/maria/ma_ft_nlq_search.c
+++ b/storage/maria/ma_ft_nlq_search.c
@@ -253,12 +253,12 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query,
{
QUEUE best;
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
- 0);
+ 0, 0, 0);
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
&best, left_root_right);
while (best.elements)
{
- my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
+ my_off_t docid= ((FT_DOC *)queue_remove_top(&best))->dpos;
if (!(*info->read_record)(info, record, docid))
{
info->update|= HA_STATE_AKTIV;
diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c
index 08702a9109e..ac23bf5fef6 100644
--- a/storage/maria/ma_key.c
+++ b/storage/maria/ma_key.c
@@ -26,7 +26,8 @@
#define CHECK_KEYS /* Enable safety checks */
-static int _ma_put_key_in_record(MARIA_HA *info,uint keynr,uchar *record);
+static int _ma_put_key_in_record(MARIA_HA *info, uint keynr,
+ my_bool unpack_blobs, uchar *record);
#define FIX_LENGTH(cs, pos, length, char_length) \
do { \
@@ -476,6 +477,9 @@ void _ma_copy_key(MARIA_KEY *to, const MARIA_KEY *from)
_ma_put_key_in_record()
info MARIA handler
keynr Key number that was used
+ unpack_blobs TRUE <=> Unpack blob columns
+ FALSE <=> Skip them. This is used by index condition
+ pushdown check function
record Store key here
Last read key is in info->lastkey
@@ -489,7 +493,7 @@ void _ma_copy_key(MARIA_KEY *to, const MARIA_KEY *from)
*/
static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
- uchar *record)
+ my_bool unpack_blobs, uchar *record)
{
reg2 uchar *key;
uchar *pos,*key_end;
@@ -582,16 +586,19 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
if (length > keyseg->length || key+length > key_end)
goto err;
#endif
- memcpy(record+keyseg->start+keyseg->bit_start,
- (char*) &blob_ptr,sizeof(char*));
- memcpy(blob_ptr,key,length);
- blob_ptr+=length;
+ if (unpack_blobs)
+ {
+ memcpy(record+keyseg->start+keyseg->bit_start,
+ (char*) &blob_ptr,sizeof(char*));
+ memcpy(blob_ptr,key,length);
+ blob_ptr+=length;
- /* The above changed info->lastkey2. Inform maria_rnext_same(). */
- info->update&= ~HA_STATE_RNEXT_SAME;
+ /* The above changed info->lastkey2. Inform maria_rnext_same(). */
+ info->update&= ~HA_STATE_RNEXT_SAME;
- _ma_store_blob_length(record+keyseg->start,
- (uint) keyseg->bit_start,length);
+ _ma_store_blob_length(record+keyseg->start,
+ (uint) keyseg->bit_start,length);
+ }
key+=length;
}
else if (keyseg->flag & HA_SWAP_KEY)
@@ -621,6 +628,7 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
DBUG_RETURN(0);
err:
+ DBUG_PRINT("info",("error"));
DBUG_RETURN(1); /* Crashed row */
} /* _ma_put_key_in_record */
@@ -634,7 +642,7 @@ int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos)
{
if (info->lastinx >= 0)
{ /* Read only key */
- if (_ma_put_key_in_record(info,(uint) info->lastinx,buf))
+ if (_ma_put_key_in_record(info, (uint)info->lastinx, TRUE, buf))
{
maria_print_error(info->s, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
@@ -649,6 +657,40 @@ int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos)
}
+
+/*
+ Save current key tuple to record and call index condition check function
+
+ SYNOPSIS
+ ma_check_index_cond()
+ info MyISAM handler
+ keynr Index we're running a scan on
+ record Record buffer to use (it is assumed that index check function
+ will look for column values there)
+
+ RETURN
+ ICP_ERROR Error
+ ICP_NO_MATCH Index condition is not satisfied, continue scanning
+ ICP_MATCH Index condition is satisfied
+ ICP_OUT_OF_RANGE Index condition is not satisfied, end the scan.
+*/
+
+int ma_check_index_cond(register MARIA_HA *info, uint keynr, uchar *record)
+{
+ if (info->index_cond_func)
+ {
+ if (_ma_put_key_in_record(info, keynr, FALSE, record))
+ {
+ maria_print_error(info->s, HA_ERR_CRASHED);
+ my_errno=HA_ERR_CRASHED;
+ return -1;
+ }
+ return info->index_cond_func(info->index_cond_func_arg);
+ }
+ return 1;
+}
+
+
/*
Retrieve auto_increment info
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 0890ff7e000..9d3e75cf4dc 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -765,6 +765,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->blobs[j].offset= share->columndef[i].offset;
j++;
}
+ if (share->columndef[i].type == FIELD_VARCHAR)
+ share->has_varchar_fields= 1;
+ if (share->columndef[i].null_bit)
+ share->has_null_fields= 1;
}
share->columndef[i].type= FIELD_LAST; /* End marker */
disk_pos= _ma_column_nr_read(disk_pos, share->column_nr,
diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c
index 85b3b463f49..e488be0ec86 100644
--- a/storage/maria/ma_rkey.c
+++ b/storage/maria/ma_rkey.c
@@ -34,6 +34,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
HA_KEYSEG *last_used_keyseg;
uint32 nextflag;
MARIA_KEY key;
+ int icp_res= 1;
DBUG_ENTER("maria_rkey");
DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d",
(long) info, (long) buf, inx, search_flag));
@@ -109,9 +110,13 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
are inserted by other threads after we got our table lock
("concurrent inserts"). The record may not even be present yet.
Keys are inserted into the index(es) before the record is
- inserted into the data file.
+ inserted into the data file.
+
+ If index condition is present, it must be either satisfied or
+ not satisfied with an out-of-range condition.
*/
- if ((*share->row_is_visible)(info))
+ if ((*share->row_is_visible)(info) &&
+ ((icp_res= ma_check_index_cond(info, inx, buf)) != 0))
break;
/* The key references a concurrently inserted record. */
@@ -123,7 +128,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
info->cur_row.lastpos= HA_OFFSET_ERROR;
break;
}
-
+
do
{
uint not_used[2];
@@ -154,18 +159,25 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
break;
/* purecov: end */
}
- } while (!(*share->row_is_visible)(info));
+
+ } while (!(*share->row_is_visible)(info) ||
+ ((icp_res= ma_check_index_cond(info, inx, buf)) == 0));
}
}
if (share->lock_key_trees)
rw_unlock(&keyinfo->root_lock);
- if (info->cur_row.lastpos == HA_OFFSET_ERROR)
+ if (info->cur_row.lastpos == HA_OFFSET_ERROR || (icp_res != 1))
{
+ if (icp_res == 2)
+ {
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
+ my_errno= HA_ERR_KEY_NOT_FOUND;
+ }
fast_ma_writeinfo(info);
goto err;
}
-
+
/* Calculate length of the found key; Used by maria_rnext_same */
if ((keyinfo->flag & HA_VAR_LENGTH_KEY))
info->last_rkey_length= _ma_keylength_part(keyinfo, info->lastkey_buff,
diff --git a/storage/maria/ma_rnext.c b/storage/maria/ma_rnext.c
index c49bbb19e83..570ea6a0c1d 100644
--- a/storage/maria/ma_rnext.c
+++ b/storage/maria/ma_rnext.c
@@ -30,6 +30,7 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx)
uint flag;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo;
+ int icp_res= 1;
uint update_mask= HA_STATE_NEXT_FOUND;
DBUG_ENTER("maria_rnext");
@@ -105,7 +106,8 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx)
if (!error)
{
- while (!(*share->row_is_visible)(info))
+ while (!(*share->row_is_visible)(info) ||
+ ((icp_res= ma_check_index_cond(info, inx, buf)) == 0))
{
/* Skip rows inserted by other threads since we got a lock */
if ((error= _ma_search_next(info, &info->last_key,
@@ -120,8 +122,11 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx)
/* Don't clear if database-changed */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
info->update|= update_mask;
+
+ if (icp_res == 2)
+ my_errno=HA_ERR_END_OF_FILE; /* got beyond the end of scanned range */
- if (error)
+ if (error || icp_res != 1)
{
if (my_errno == HA_ERR_KEY_NOT_FOUND)
my_errno=HA_ERR_END_OF_FILE;
diff --git a/storage/maria/ma_rnext_same.c b/storage/maria/ma_rnext_same.c
index cbd81d20816..f67a76a366f 100644
--- a/storage/maria/ma_rnext_same.c
+++ b/storage/maria/ma_rnext_same.c
@@ -30,6 +30,7 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf)
int error;
uint inx,not_used[2];
MARIA_KEYDEF *keyinfo;
+ int icp_res= 1;
DBUG_ENTER("maria_rnext_same");
if ((int) (inx= info->lastinx) < 0 ||
@@ -80,7 +81,8 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf)
break;
}
/* Skip rows that are inserted by other threads since we got a lock */
- if ((info->s->row_is_visible)(info))
+ if ((info->s->row_is_visible)(info) &&
+ ((icp_res= ma_check_index_cond(info, inx, buf)) != 0))
break;
}
}
@@ -90,7 +92,10 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf)
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
info->update|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME;
- if (error)
+ if (icp_res == 2)
+ my_errno=HA_ERR_END_OF_FILE; /* got beyond the end of scanned range */
+
+ if (error || icp_res != 1)
{
if (my_errno == HA_ERR_KEY_NOT_FOUND)
my_errno=HA_ERR_END_OF_FILE;
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index 5c5bd8f8d6c..a36bb980145 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -939,7 +939,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, uchar *,uchar*)) info->key_cmp,
- (void*) info))
+ (void*) info, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
@@ -988,7 +988,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
- VOID(queue_remove(&queue,0));
+ VOID(queue_remove_top(&queue));
/* Put room used by buffer to use in other buffer */
for (refpek= (BUFFPEK**) &queue_top(&queue);
@@ -1013,7 +1013,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
else if (error == -1)
goto err; /* purecov: inspected */
- queue_replaced(&queue); /* Top element has been replaced */
+ queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 2fbc84bae5f..4195be4a53a 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -378,6 +378,8 @@ typedef struct st_maria_share
my_bool temporary;
/* Below flag is needed to make log tables work with concurrent insert */
my_bool is_log_table;
+ my_bool has_null_fields;
+ my_bool has_varchar_fields; /* If table has varchar fields */
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
@@ -484,6 +486,7 @@ typedef struct st_maria_block_scan
MARIA_RECORD_POS row_base_page;
} MARIA_BLOCK_SCAN;
+typedef ICP_RESULT (*index_cond_func_t)(void *param);
struct st_maria_handler
{
@@ -588,6 +591,9 @@ struct st_maria_handler
uchar *maria_rtree_recursion_state; /* For RTREE */
uchar length_buff[5]; /* temp buff to store blob lengths */
int maria_rtree_recursion_depth;
+
+ index_cond_func_t index_cond_func; /* Index condition function */
+ void *index_cond_func_arg; /* parameter for the func */
};
/* Some defines used by maria-functions */
@@ -1261,3 +1267,6 @@ extern my_bool maria_flush_log_for_page_none(uchar *page,
pgcache_page_no_t page_no,
uchar *data_ptr);
extern PAGECACHE *maria_log_pagecache;
+extern void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func,
+ void *func_arg);
+int ma_check_index_cond(register MARIA_HA *info, uint keynr, uchar *record);
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 983a38e69e7..8332af60de5 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -590,7 +590,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
Create a global priority queue in preparation for making
temporary Huffman trees.
*/
- if (init_queue(&queue,256,0,0,compare_huff_elements,0))
+ if (init_queue(&queue, 256, 0, 0, compare_huff_elements, 0, 0, 0))
goto err;
/*
@@ -1523,7 +1523,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
if (queue.max_elements < found)
{
delete_queue(&queue);
- if (init_queue(&queue,found,0,0,compare_huff_elements,0))
+ if (init_queue(&queue,found, 0, 0, compare_huff_elements, 0, 0, 0))
return -1;
}
@@ -1627,8 +1627,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=found/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
bytes_packed=0; bits_packed=0;
@@ -1639,12 +1638,9 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Popping from a priority queue includes a re-ordering of the queue,
to get the next least incidence element to the top.
*/
- a=(HUFF_ELEMENT*) queue_remove(&queue,0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b=(HUFF_ELEMENT*) queue.root[1];
+ a=(HUFF_ELEMENT*) queue_remove_top(&queue);
+ /* Copy the next least incidence element */
+ b=(HUFF_ELEMENT*) queue_top(&queue);
/* Get a new element from the element buffer. */
new_huff_el=huff_tree->element_buffer+found+i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1666,8 +1662,8 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Replace the copied top element by the new element and re-order the
queue.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
huff_tree->root=(HUFF_ELEMENT*) queue.root[1];
huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8;
@@ -1798,8 +1794,7 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=(found+1)/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
for (i=0 ; i < found-1 ; i++)
@@ -1813,12 +1808,9 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
incidence). Popping from a priority queue includes a re-ordering
of the queue, to get the next least incidence element to the top.
*/
- a= (my_off_t*) queue_remove(&queue, 0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b= (my_off_t*) queue.root[1];
+ a= (my_off_t*) queue_remove_top(&queue);
+ /* Copy the next least incidence element. */
+ b= (my_off_t*) queue_top(&queue);
/* Create a new element in a local (automatic) buffer. */
new_huff_el= element_buffer + i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1838,8 +1830,8 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
queue. This successively replaces the references to counts by
references to HUFF_ELEMENTs.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
DBUG_RETURN(bytes_packed+(bits_packed+7)/8);
}
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index 3a6368f338d..dc7eb763b77 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -482,16 +482,18 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
static void _ftb_init_index_search(FT_INFO *ftb)
{
- int i;
+ uint i;
FTB_WORD *ftbw;
if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
- for (i=ftb->queue.elements; i; i--)
+ for (i= queue_last_element(&ftb->queue);
+ (int) i >= (int) queue_first_element(&ftb->queue);
+ i--)
{
- ftbw=(FTB_WORD *)(ftb->queue.root[i]);
+ ftbw=(FTB_WORD *)(queue_element(&ftb->queue, i));
if (ftbw->flags & FTB_FLAG_TRUNC)
{
@@ -595,12 +597,12 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query,
sizeof(void *))))
goto err;
reinit_queue(&ftb->queue, ftb->queue.max_elements, 0, 0,
- (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0);
+ (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0, 0, 0);
for (ftbw= ftb->last_word; ftbw; ftbw= ftbw->prev)
queue_insert(&ftb->queue, (uchar *)ftbw);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
sizeof(FTB_WORD *)*ftb->queue.elements);
- memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements);
+ memcpy(ftb->list, &queue_top(&ftb->queue), sizeof(FTB_WORD *)*ftb->queue.elements);
my_qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *),
(qsort2_cmp)FTB_WORD_cmp_list, (void*) ftb->charset);
if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC;
@@ -839,7 +841,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
/* update queue */
_ft2_search(ftb, ftbw, 0);
- queue_replaced(& ftb->queue);
+ queue_replace_top(&ftb->queue);
}
ftbe=ftb->root;
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index 90ad2d635b7..bcce2cc8d60 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -250,12 +250,12 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query,
{
QUEUE best;
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
- 0);
+ 0, 0, 0);
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
&best, left_root_right);
while (best.elements)
{
- my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
+ my_off_t docid= ((FT_DOC *)queue_remove_top(&best))->dpos;
if (!(*info->read_record)(info,docid,record))
{
info->update|= HA_STATE_AKTIV;
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 09a20383937..b2fad816eba 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -746,6 +746,16 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
int_table_flags|= HA_HAS_OLD_CHECKSUM;
}
+ /*
+ For static size rows, tell MariaDB that we will access all bytes
+ in the record when writing it. This signals MariaDB to initalize
+ the full row to ensure we don't get any errors from valgrind and
+ that all bytes in the row is properly reset.
+ */
+ if ((file->s->options & HA_OPTION_PACK_RECORD) &&
+ (file->s->has_varchar_fields | file->s->has_null_fields))
+ int_table_flags|= HA_RECORD_MUST_BE_CLEAN_ON_WRITE;
+
for (i= 0; i < table->s->keys; i++)
{
plugin_ref parser= table->key_info[i].parser;
@@ -771,6 +781,8 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
int ha_myisam::close(void)
{
MI_INFO *tmp=file;
+ if (!tmp)
+ return 0;
file=0;
return mi_close(tmp);
}
@@ -810,7 +822,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
param.thd = thd;
param.op_name = "check";
param.db_name= table->s->db.str;
- param.table_name= table->alias;
+ param.table_name= table->alias.c_ptr();
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
param.stats_method= (enum_handler_stats_method)thd->variables.myisam_stats_method;
@@ -903,7 +915,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
param.thd = thd;
param.op_name= "analyze";
param.db_name= table->s->db.str;
- param.table_name= table->alias;
+ param.table_name= table->alias.c_ptr();
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
param.using_global_keycache = 1;
@@ -1129,7 +1141,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
DBUG_ENTER("ha_myisam::repair");
param.db_name= table->s->db.str;
- param.table_name= table->alias;
+ param.table_name= table->alias.c_ptr();
param.tmpfile_createflag = O_RDWR | O_TRUNC;
param.using_global_keycache = 1;
param.thd= thd;
@@ -1701,6 +1713,48 @@ int ha_myisam::delete_row(const uchar *buf)
return mi_delete(file,buf);
}
+
+C_MODE_START
+
+ICP_RESULT index_cond_func_myisam(void *arg)
+{
+ ha_myisam *h= (ha_myisam*)arg;
+ if (h->end_range)
+ {
+ if (h->compare_key2(h->end_range) > 0)
+ return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
+ }
+ return (ICP_RESULT) test(h->pushed_idx_cond->val_int());
+}
+
+C_MODE_END
+
+
+int ha_myisam::index_init(uint idx, bool sorted)
+{
+ active_index=idx;
+ if (pushed_idx_cond_keyno == idx)
+ mi_set_index_cond_func(file, index_cond_func_myisam, this);
+ return 0;
+}
+
+
+int ha_myisam::index_end()
+{
+ active_index=MAX_KEY;
+ //pushed_idx_cond_keyno= MAX_KEY;
+ mi_set_index_cond_func(file, NULL, 0);
+ in_range_check_pushed_down= FALSE;
+ ds_mrr.dsmrr_close();
+ return 0;
+}
+
+int ha_myisam::rnd_end()
+{
+ ds_mrr.dsmrr_close();
+ return 0;
+}
+
int ha_myisam::index_read_map(uchar *buf, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
@@ -1806,6 +1860,16 @@ int ha_myisam::info(uint flag)
stats.max_data_file_length= misam_info.max_data_file_length;
stats.max_index_file_length= misam_info.max_index_file_length;
stats.create_time= (ulong) misam_info.create_time;
+ /*
+ We want the value of stats.mrr_length_per_rec to be platform independent.
+ The size of the chunk at the end of the join buffer used for MRR needs
+ is calculated now basing on the values passed in the stats structure.
+ The remaining part of the join buffer is used for records. A different
+ number of records in the buffer results in a different number of buffer
+ refills and in a different order of records in the result set.
+ */
+ stats.mrr_length_per_rec= misam_info.reflength + 8; // 8=max(sizeof(void *))
+
ref_length= misam_info.reflength;
share->db_options_in_use= misam_info.options;
stats.block_size= myisam_block_size; /* record block size */
@@ -1861,8 +1925,13 @@ int ha_myisam::extra(enum ha_extra_function operation)
return mi_extra(file, operation, 0);
}
+
int ha_myisam::reset(void)
{
+ pushed_idx_cond= NULL;
+ pushed_idx_cond_keyno= MAX_KEY;
+ mi_set_index_cond_func(file, NULL, 0);
+ ds_mrr.dsmrr_close();
return mi_reset(file);
}
@@ -2145,6 +2214,62 @@ static int myisam_init(void *p)
return 0;
}
+/****************************************************************************
+ * MyISAM MRR implementation: use DS-MRR
+ ***************************************************************************/
+
+int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf)
+{
+ return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf);
+}
+
+int ha_myisam::multi_range_read_next(char **range_info)
+{
+ return ds_mrr.dsmrr_next(range_info);
+}
+
+ha_rows ha_myisam::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)
+{
+ /*
+ This call is here because there is no location where this->table would
+ already be known.
+ TODO: consider moving it into some per-query initialization call.
+ */
+ ds_mrr.init(this, table);
+ return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
+ flags, cost);
+}
+
+ha_rows ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost)
+{
+ ds_mrr.init(this, table);
+ return ds_mrr.dsmrr_info(keyno, n_ranges, keys, key_parts, bufsz, flags, cost);
+}
+
+/* MyISAM MRR implementation ends */
+
+
+/* Index condition pushdown implementation*/
+
+
+Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
+{
+ pushed_idx_cond_keyno= keyno_arg;
+ pushed_idx_cond= idx_cond_arg;
+ in_range_check_pushed_down= TRUE;
+ if (active_index == pushed_idx_cond_keyno)
+ mi_set_index_cond_func(file, index_cond_func_myisam, this);
+ return NULL;
+}
+
+
struct st_mysql_storage_engine myisam_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index d8f307c4aa7..b9700e0ef90 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -35,6 +35,10 @@ extern ulong myisam_sort_buffer_size;
extern TYPELIB myisam_recover_typelib;
extern ulong myisam_recover_options;
+C_MODE_START
+ICP_RESULT index_cond_func_myisam(void *arg);
+C_MODE_END
+
class ha_myisam: public handler
{
MI_INFO *file;
@@ -51,11 +55,15 @@ class ha_myisam: public handler
const char *index_type(uint key_number);
const char **bas_ext() const;
ulonglong table_flags() const { return int_table_flags; }
+ int index_init(uint idx, bool sorted);
+ int index_end();
+ int rnd_end();
+
ulong index_flags(uint inx, uint part, bool all_parts) const
{
return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
- HA_READ_ORDER | HA_KEYREAD_ONLY);
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
}
uint max_supported_keys() const { return MI_MAX_KEY; }
uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; }
@@ -148,4 +156,24 @@ class ha_myisam: public handler
{
return file;
}
+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(char **range_info);
+ 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);
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+
+ /* Index condition pushdown implementation */
+ Item *idx_cond_push(uint keyno, Item* idx_cond);
+private:
+ DsMrr_impl ds_mrr;
+ friend ICP_RESULT index_cond_func_myisam(void *arg);
};
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index 7b8f5249b3e..648e5fb0024 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -410,6 +410,12 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
DBUG_RETURN(error);
} /* mi_extra */
+void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func,
+ void *func_arg)
+{
+ info->index_cond_func= func;
+ info->index_cond_func_arg= func_arg;
+}
/*
Start/Stop Inserting Duplicates Into a Table, WL#1648.
diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
index 94f3f34ec58..52273f013ec 100644
--- a/storage/myisam/mi_key.c
+++ b/storage/myisam/mi_key.c
@@ -31,7 +31,8 @@
set_if_smaller(char_length,length); \
} while(0)
-static int _mi_put_key_in_record(MI_INFO *info,uint keynr,uchar *record);
+static int _mi_put_key_in_record(MI_INFO *info,uint keynr,
+ my_bool unpack_blobs, uchar *record);
/*
Make a intern key from a record
@@ -312,6 +313,9 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
_mi_put_key_in_record()
info MyISAM handler
keynr Key number that was used
+ unpack_blobs TRUE <=> Unpack blob columns
+ FALSE <=> Skip them. This is used by index condition
+ pushdown check function
record Store key here
Last read key is in info->lastkey
@@ -325,7 +329,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
*/
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
- uchar *record)
+ my_bool unpack_blobs, uchar *record)
{
reg2 uchar *key;
uchar *pos,*key_end;
@@ -418,16 +422,19 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
if (length > keyseg->length || key+length > key_end)
goto err;
#endif
- memcpy(record+keyseg->start+keyseg->bit_start,
- (char*) &blob_ptr,sizeof(char*));
- memcpy(blob_ptr,key,length);
- blob_ptr+=length;
+ if (unpack_blobs)
+ {
+ memcpy(record+keyseg->start+keyseg->bit_start,
+ (char*) &blob_ptr,sizeof(char*));
+ memcpy(blob_ptr,key,length);
+ blob_ptr+=length;
- /* The above changed info->lastkey2. Inform mi_rnext_same(). */
- info->update&= ~HA_STATE_RNEXT_SAME;
+ /* The above changed info->lastkey2. Inform mi_rnext_same(). */
+ info->update&= ~HA_STATE_RNEXT_SAME;
- _mi_store_blob_length(record+keyseg->start,
- (uint) keyseg->bit_start,length);
+ _mi_store_blob_length(record+keyseg->start,
+ (uint) keyseg->bit_start,length);
+ }
key+=length;
}
else if (keyseg->flag & HA_SWAP_KEY)
@@ -471,7 +478,7 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
{
if (info->lastinx >= 0)
{ /* Read only key */
- if (_mi_put_key_in_record(info,(uint) info->lastinx,buf))
+ if (_mi_put_key_in_record(info,(uint) info->lastinx, TRUE, buf))
{
mi_print_error(info->s, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
@@ -487,6 +494,34 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
/*
+ Save current key tuple to record and call index condition check function
+
+ SYNOPSIS
+ mi_check_index_cond()
+ info MyISAM handler
+ keynr Index we're running a scan on
+ record Record buffer to use (it is assumed that index check function
+ will look for column values there)
+
+ RETURN
+ ICP_ERROR Error
+ ICP_NO_MATCH Index condition is not satisfied, continue scanning
+ ICP_MATCH Index condition is satisfied
+ ICP_OUT_OF_RANGE Index condition is not satisfied, end the scan.
+*/
+
+int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
+{
+ if (_mi_put_key_in_record(info, keynr, FALSE, record))
+ {
+ mi_print_error(info->s, HA_ERR_CRASHED);
+ my_errno=HA_ERR_CRASHED;
+ return ICP_ERROR;
+ }
+ return info->index_cond_func(info->index_cond_func_arg);
+}
+
+/*
Retrieve auto_increment info
SYNOPSIS
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 9d69f8622e8..89a0ef61081 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -79,14 +79,14 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err;
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
- key_parts,unique_key_parts,fulltext_keys,uniques;
+ key_parts,unique_key_parts,base_key_parts,fulltext_keys,uniques;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
uchar *disk_cache, *disk_pos, *end_pos;
MI_INFO info,*m_info,*old_info;
MYISAM_SHARE share_buff,*share;
- ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
- my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
+ ulong *rec_per_key_part= 0;
+ my_off_t *key_root, *key_del;
ulonglong max_key_file_length, max_data_file_length;
DBUG_ENTER("mi_open");
@@ -111,9 +111,6 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
share= &share_buff;
bzero((uchar*) &share_buff,sizeof(share_buff));
- share_buff.state.rec_per_key_part=rec_per_key_part;
- share_buff.state.key_root=key_root;
- share_buff.state.key_del=key_del;
share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
strlen(name_buff),
dflt_key_cache);
@@ -203,7 +200,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
keys= (uint) share->state.header.keys;
uniques= (uint) share->state.header.uniques;
fulltext_keys= (uint) share->state.header.fulltext_keys;
- key_parts= mi_uint2korr(share->state.header.key_parts);
+ base_key_parts= key_parts= mi_uint2korr(share->state.header.key_parts);
unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
if (len != MI_STATE_INFO_SIZE)
{
@@ -213,7 +210,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
share->state_diff_length=len-MI_STATE_INFO_SIZE;
- mi_state_info_read(disk_cache, &share->state);
+ if (!mi_state_info_read(disk_cache, &share->state))
+ goto err;
+ rec_per_key_part= share->state.rec_per_key_part;
+ key_root= share->state.key_root;
+ key_del= share->state.key_del;
+
len= mi_uint2korr(share->state.header.base_info_length);
if (len != MI_BASE_INFO_SIZE)
{
@@ -296,7 +298,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
if (!my_multi_malloc(MY_WME,
&share,sizeof(*share),
- &share->state.rec_per_key_part,sizeof(long)*key_parts,
+ &share->state.rec_per_key_part,
+ sizeof(long)*base_key_parts,
&share->keyinfo,keys*sizeof(MI_KEYDEF),
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
&share->keyparts,
@@ -320,7 +323,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
errpos=4;
*share=share_buff;
memcpy((char*) share->state.rec_per_key_part,
- (char*) rec_per_key_part, sizeof(long)*key_parts);
+ (char*) rec_per_key_part, sizeof(long)*base_key_parts);
memcpy((char*) share->state.key_root,
(char*) key_root, sizeof(my_off_t)*keys);
memcpy((char*) share->state.key_del,
@@ -666,6 +669,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
pthread_mutex_unlock(&THR_LOCK_myisam);
bzero(info.buff, share->base.max_key_block_length * 2);
+ my_free(rec_per_key_part, MYF(MY_ALLOW_ZERO_PTR));
if (myisam_log_file >= 0)
{
@@ -695,6 +699,7 @@ err:
case 3:
if (! lock_error)
VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
+ my_free(rec_per_key_part, MYF(MY_ALLOW_ZERO_PTR));
/* fall through */
case 2:
my_afree(disk_cache);
@@ -982,6 +987,16 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
ptr+= state->state_diff_length;
+ if (!state->rec_per_key_part)
+ {
+ if (!my_multi_malloc(MY_WME,
+ &state->rec_per_key_part,sizeof(long)*key_parts,
+ &state->key_root, keys*sizeof(my_off_t),
+ &state->key_del, key_blocks*sizeof(my_off_t),
+ NullS))
+ return(0);
+ }
+
for (i=0; i < keys; i++)
{
state->key_root[i]= mi_sizekorr(ptr); ptr +=8;
diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c
index f20b0366683..da757d270bc 100644
--- a/storage/myisam/mi_rkey.c
+++ b/storage/myisam/mi_rkey.c
@@ -29,6 +29,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
MI_KEYDEF *keyinfo;
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
+ ICP_RESULT res= ICP_NO_MATCH;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d",
(long) info, (long) buf, inx, search_flag));
@@ -105,55 +106,62 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
saved the current data_file_length. Concurrent inserts always go
to the end of the file. So we can test if the found key
references a new record.
+
+ If we are searching for a partial key (or using >, >=, < or <=) and
+ the data is outside of the data file, we need to continue searching
+ for the first key inside the data file.
+
+ We do also continue searching if an index condition check function
+ is available.
*/
- if (info->lastpos >= info->state->data_file_length)
+ while ((info->lastpos >= info->state->data_file_length &&
+ (search_flag != HA_READ_KEY_EXACT ||
+ last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) ||
+ (info->index_cond_func &&
+ (res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
- /* The key references a concurrently inserted record. */
+ uint not_used[2];
+ /*
+ Skip rows that are inserted by other threads since we got a lock
+ Note that this can only happen if we are not searching after an
+ full length exact key, because the keys are sorted
+ according to position
+ */
+ if (_mi_search_next(info, keyinfo, info->lastkey,
+ info->lastkey_length,
+ myisam_readnext_vec[search_flag],
+ info->s->state.key_root[inx]))
+ break;
+ /*
+ Check that the found key does still match the search.
+ _mi_search_next() delivers the next key regardless of its
+ value.
+ */
if (search_flag == HA_READ_KEY_EXACT &&
- last_used_keyseg == keyinfo->seg + keyinfo->keysegs)
+ ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length,
+ SEARCH_FIND, not_used))
{
- /* Simply ignore the key if it matches exactly. (Bug #29838) */
my_errno= HA_ERR_KEY_NOT_FOUND;
info->lastpos= HA_OFFSET_ERROR;
+ break;
}
- else
- {
- /*
- If searching for a partial key (or using >, >=, < or <=) and
- the data is outside of the data file, we need to continue
- searching for the first key inside the data file.
- */
- do
- {
- uint not_used[2];
- /*
- Skip rows that are inserted by other threads since we got
- a lock. Note that this can only happen if we are not
- searching after a full length exact key, because the keys
- are sorted according to position.
- */
- if (_mi_search_next(info, keyinfo, info->lastkey,
- info->lastkey_length,
- myisam_readnext_vec[search_flag],
- info->s->state.key_root[inx]))
- break; /* purecov: inspected */
- /*
- Check that the found key does still match the search.
- _mi_search_next() delivers the next key regardless of its
- value.
- */
- if (search_flag == HA_READ_KEY_EXACT &&
- ha_key_cmp(keyinfo->seg, key_buff, info->lastkey,
- use_key_length, SEARCH_FIND, not_used))
- {
- /* purecov: begin inspected */
- my_errno= HA_ERR_KEY_NOT_FOUND;
- info->lastpos= HA_OFFSET_ERROR;
- break;
- /* purecov: end */
- }
- } while (info->lastpos >= info->state->data_file_length);
- }
+ }
+ if (res == ICP_OUT_OF_RANGE)
+ {
+ info->lastpos= HA_OFFSET_ERROR;
+ if (share->concurrent_insert)
+ rw_unlock(&share->key_root_lock[inx]);
+ DBUG_RETURN((my_errno= HA_ERR_KEY_NOT_FOUND));
+ }
+ /*
+ Error if no row found within the data file. (Bug #29838)
+ Do not overwrite my_errno if already at HA_OFFSET_ERROR.
+ */
+ if (info->lastpos != HA_OFFSET_ERROR &&
+ info->lastpos >= info->state->data_file_length)
+ {
+ info->lastpos= HA_OFFSET_ERROR;
+ my_errno= HA_ERR_KEY_NOT_FOUND;
}
}
}
diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c
index b9bbda3cacb..b1c261dd6b1 100644
--- a/storage/myisam/mi_rnext.c
+++ b/storage/myisam/mi_rnext.c
@@ -28,6 +28,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
{
int error,changed;
uint flag;
+ ICP_RESULT res= 0;
uint update_mask= HA_STATE_NEXT_FOUND;
DBUG_ENTER("mi_rnext");
@@ -96,23 +97,36 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
}
}
- if (info->s->concurrent_insert)
+ if (!error)
{
- if (!error)
+ while ((info->s->concurrent_insert &&
+ info->lastpos >= info->state->data_file_length) ||
+ (info->index_cond_func &&
+ (res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
- while (info->lastpos >= info->state->data_file_length)
- {
- /* Skip rows inserted by other threads since we got a lock */
- if ((error=_mi_search_next(info,info->s->keyinfo+inx,
- info->lastkey,
- info->lastkey_length,
- SEARCH_BIGGER,
- info->s->state.key_root[inx])))
- break;
- }
+ /*
+ Skip rows that are either inserted by other threads since
+ we got a lock or do not match pushed index conditions
+ */
+ if ((error=_mi_search_next(info,info->s->keyinfo+inx,
+ info->lastkey,
+ info->lastkey_length,
+ SEARCH_BIGGER,
+ info->s->state.key_root[inx])))
+ break;
+ }
+ if (!error && res == ICP_OUT_OF_RANGE)
+ {
+ if (info->s->concurrent_insert)
+ rw_unlock(&info->s->key_root_lock[inx]);
+ info->lastpos= HA_OFFSET_ERROR;
+ DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
}
- rw_unlock(&info->s->key_root_lock[inx]);
}
+
+ if (info->s->concurrent_insert)
+ rw_unlock(&info->s->key_root_lock[inx]);
+
/* Don't clear if database-changed */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
info->update|= update_mask;
diff --git a/storage/myisam/mi_rnext_same.c b/storage/myisam/mi_rnext_same.c
index 1892fe3e1e0..df3b678d663 100644
--- a/storage/myisam/mi_rnext_same.c
+++ b/storage/myisam/mi_rnext_same.c
@@ -75,8 +75,13 @@ int mi_rnext_same(MI_INFO *info, uchar *buf)
info->lastpos= HA_OFFSET_ERROR;
break;
}
- /* Skip rows that are inserted by other threads since we got a lock */
- if (info->lastpos < info->state->data_file_length)
+ /*
+ Skip
+ - rows that are inserted by other threads since we got a lock
+ - rows that don't match index condition */
+ if (info->lastpos < info->state->data_file_length &&
+ (!info->index_cond_func ||
+ mi_check_index_cond(info, inx, buf) != ICP_NO_MATCH))
break;
}
}
diff --git a/storage/myisam/mi_rprev.c b/storage/myisam/mi_rprev.c
index d1407012590..93bd224bd56 100644
--- a/storage/myisam/mi_rprev.c
+++ b/storage/myisam/mi_rprev.c
@@ -51,22 +51,36 @@ int mi_rprev(MI_INFO *info, uchar *buf, int inx)
error=_mi_search(info,share->keyinfo+inx,info->lastkey,
USE_WHOLE_KEY, flag, share->state.key_root[inx]);
- if (share->concurrent_insert)
+ if (!error)
{
- if (!error)
+ int res= 0;
+ while ((share->concurrent_insert &&
+ info->lastpos >= info->state->data_file_length) ||
+ (info->index_cond_func &&
+ !(res= mi_check_index_cond(info, inx, buf))))
{
- while (info->lastpos >= info->state->data_file_length)
- {
- /* Skip rows that are inserted by other threads since we got a lock */
- if ((error=_mi_search_next(info,share->keyinfo+inx,info->lastkey,
- info->lastkey_length,
- SEARCH_SMALLER,
- share->state.key_root[inx])))
- break;
- }
+ /*
+ Skip rows that are either inserted by other threads since
+ we got a lock or do not match pushed index conditions
+ */
+ if ((error=_mi_search_next(info,share->keyinfo+inx,info->lastkey,
+ info->lastkey_length,
+ SEARCH_SMALLER,
+ share->state.key_root[inx])))
+ break;
+ }
+ if (!error && res == 2)
+ {
+ if (share->concurrent_insert)
+ rw_unlock(&share->key_root_lock[inx]);
+ info->lastpos= HA_OFFSET_ERROR;
+ DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
}
- rw_unlock(&share->key_root_lock[inx]);
}
+
+ if (share->concurrent_insert)
+ rw_unlock(&share->key_root_lock[inx]);
+
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
info->update|= HA_STATE_PREV_FOUND;
if (error)
diff --git a/storage/myisam/mi_test_all.sh b/storage/myisam/mi_test_all.sh
index 5989d9cfaf0..c6bc686e885 100755
--- a/storage/myisam/mi_test_all.sh
+++ b/storage/myisam/mi_test_all.sh
@@ -5,6 +5,7 @@
valgrind="valgrind --alignment=8 --leak-check=yes"
silent="-s"
+rm -f test1.TMD
if test -f mi_test1$MACH ; then suffix=$MACH ; else suffix=""; fi
./mi_test1$suffix $silent
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index a0570b20b4f..20974e0b717 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -235,6 +235,7 @@ typedef struct st_mi_isam_share
rw_lock_t mmap_lock;
} MYISAM_SHARE;
+typedef ICP_RESULT (*index_cond_func_t)(void *param);
struct st_myisam_info
{
@@ -304,6 +305,8 @@ struct st_myisam_info
my_bool page_changed;
/* If info->buff has to be reread for rnext */
my_bool buff_used;
+ index_cond_func_t index_cond_func; /* Index condition function */
+ void *index_cond_func_arg; /* parameter for the func */
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
@@ -726,6 +729,7 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
int mi_munmap_file(MI_INFO *info);
void mi_remap_file(MI_INFO *info, my_off_t size);
+int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record);
/* Functions needed by mi_check */
int killed_ptr(HA_CHECK *param);
void mi_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...));
@@ -734,6 +738,8 @@ void mi_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...));
#ifdef THREAD
pthread_handler_t thr_find_all_keys(void *arg);
#endif
+extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func,
+ void *func_arg);
int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file,
ulonglong *dirty_part_map);
#ifdef __cplusplus
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index ba3ff3cdf0d..17add155193 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -576,7 +576,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
Create a global priority queue in preparation for making
temporary Huffman trees.
*/
- if (init_queue(&queue,256,0,0,compare_huff_elements,0))
+ if (init_queue(&queue, 256, 0, 0, compare_huff_elements, 0, 0, 0))
goto err;
/*
@@ -1511,7 +1511,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
if (queue.max_elements < found)
{
delete_queue(&queue);
- if (init_queue(&queue,found,0,0,compare_huff_elements,0))
+ if (init_queue(&queue,found, 0, 0, compare_huff_elements, 0, 0, 0))
return -1;
}
@@ -1615,8 +1615,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=found/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
bytes_packed=0; bits_packed=0;
@@ -1627,12 +1626,9 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Popping from a priority queue includes a re-ordering of the queue,
to get the next least incidence element to the top.
*/
- a=(HUFF_ELEMENT*) queue_remove(&queue,0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b=(HUFF_ELEMENT*) queue.root[1];
+ a=(HUFF_ELEMENT*) queue_remove_top(&queue);
+ /* Copy the next least incidence element */
+ b=(HUFF_ELEMENT*) queue_top(&queue);
/* Get a new element from the element buffer. */
new_huff_el=huff_tree->element_buffer+found+i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1654,8 +1650,8 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Replace the copied top element by the new element and re-order the
queue.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
huff_tree->root=(HUFF_ELEMENT*) queue.root[1];
huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8;
@@ -1786,8 +1782,7 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=(found+1)/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
for (i=0 ; i < found-1 ; i++)
@@ -1801,12 +1796,9 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
incidence). Popping from a priority queue includes a re-ordering
of the queue, to get the next least incidence element to the top.
*/
- a= (my_off_t*) queue_remove(&queue, 0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b= (my_off_t*) queue.root[1];
+ a= (my_off_t*) queue_remove_top(&queue);
+ /* Copy the next least incidence element. */
+ b= (my_off_t*) queue_top(&queue);
/* Create a new element in a local (automatic) buffer. */
new_huff_el= element_buffer + i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1826,8 +1818,8 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
queue. This successively replaces the references to counts by
references to HUFF_ELEMENTs.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
DBUG_RETURN(bytes_packed+(bits_packed+7)/8);
}
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index fd0bd971e10..2b6d5167c93 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -920,7 +920,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, uchar *,uchar*)) info->key_cmp,
- (void*) info))
+ (void*) info, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
@@ -969,7 +969,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
- VOID(queue_remove(&queue,0));
+ VOID(queue_remove_top(&queue));
/* Put room used by buffer to use in other buffer */
for (refpek= (BUFFPEK**) &queue_top(&queue);
@@ -994,7 +994,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
else if (error == -1)
goto err; /* purecov: inspected */
- queue_replaced(&queue); /* Top element has been replaced */
+ queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
diff --git a/storage/myisammrg/myrg_queue.c b/storage/myisammrg/myrg_queue.c
index d2579053784..cf862b53b86 100644
--- a/storage/myisammrg/myrg_queue.c
+++ b/storage/myisammrg/myrg_queue.c
@@ -52,7 +52,7 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
if (init_queue(q,info->tables, 0,
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
- info->open_tables->table->s->keyinfo[inx].seg))
+ info->open_tables->table->s->keyinfo[inx].seg, 0, 0))
error=my_errno;
}
else
@@ -60,7 +60,7 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
if (reinit_queue(q,info->tables, 0,
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
- info->open_tables->table->s->keyinfo[inx].seg))
+ info->open_tables->table->s->keyinfo[inx].seg, 0, 0))
error=my_errno;
}
}
diff --git a/storage/myisammrg/myrg_rnext.c b/storage/myisammrg/myrg_rnext.c
index 82d5cbf38b1..1442ee08dd4 100644
--- a/storage/myisammrg/myrg_rnext.c
+++ b/storage/myisammrg/myrg_rnext.c
@@ -32,7 +32,7 @@ int myrg_rnext(MYRG_INFO *info, uchar *buf, int inx)
{
if (err == HA_ERR_END_OF_FILE)
{
- queue_remove(&(info->by_key),0);
+ queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
@@ -43,7 +43,7 @@ int myrg_rnext(MYRG_INFO *info, uchar *buf, int inx)
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
- queue_replaced(&(info->by_key));
+ queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
diff --git a/storage/myisammrg/myrg_rnext_same.c b/storage/myisammrg/myrg_rnext_same.c
index ad7bbfb0f6e..14b41dbe756 100644
--- a/storage/myisammrg/myrg_rnext_same.c
+++ b/storage/myisammrg/myrg_rnext_same.c
@@ -29,7 +29,7 @@ int myrg_rnext_same(MYRG_INFO *info, uchar *buf)
{
if (err == HA_ERR_END_OF_FILE)
{
- queue_remove(&(info->by_key),0);
+ queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
@@ -40,7 +40,7 @@ int myrg_rnext_same(MYRG_INFO *info, uchar *buf)
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
- queue_replaced(&(info->by_key));
+ queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
diff --git a/storage/myisammrg/myrg_rprev.c b/storage/myisammrg/myrg_rprev.c
index 66c94974940..0c560a0b73d 100644
--- a/storage/myisammrg/myrg_rprev.c
+++ b/storage/myisammrg/myrg_rprev.c
@@ -32,7 +32,7 @@ int myrg_rprev(MYRG_INFO *info, uchar *buf, int inx)
{
if (err == HA_ERR_END_OF_FILE)
{
- queue_remove(&(info->by_key),0);
+ queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
@@ -43,7 +43,7 @@ int myrg_rprev(MYRG_INFO *info, uchar *buf, int inx)
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
- queue_replaced(&(info->by_key));
+ queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_prev is as simple as one queue_top */
diff --git a/storage/oqgraph/ha_oqgraph.cc b/storage/oqgraph/ha_oqgraph.cc
index cf9ef3d8997..fa506363a51 100644
--- a/storage/oqgraph/ha_oqgraph.cc
+++ b/storage/oqgraph/ha_oqgraph.cc
@@ -766,7 +766,7 @@ int ha_oqgraph::fill_record(byte *record, const open_query::row &row)
if (row.weight_indicator)
{
field[3]->set_notnull();
- field[3]->store((double) row.weight);
+ field[3]->store((double) row.weight, 0);
}
if (row.seq_indicator)
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index ee060f61c75..42b818c41e1 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -125,6 +125,12 @@ static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
static bool innodb_inited = 0;
+C_MODE_START
+static int index_cond_func_innodb(void *arg);
+C_MODE_END
+
+
+
#define INSIDE_HA_INNOBASE_CC
/* In the Windows plugin, the return value of current_thd is
@@ -3229,7 +3235,7 @@ ha_innobase::index_flags(
const
{
return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
- | HA_READ_RANGE | HA_KEYREAD_ONLY);
+ | HA_READ_RANGE | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
}
/****************************************************************//**
@@ -4619,8 +4625,9 @@ build_template(
THD* thd, /*!< in: current user thread, used
only if templ_type is
ROW_MYSQL_REC_FIELDS */
- TABLE* table, /*!< in: MySQL table */
- uint templ_type) /*!< in: ROW_MYSQL_WHOLE_ROW or
+ 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 */
{
dict_index_t* index;
@@ -4634,7 +4641,9 @@ build_template(
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;
+
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
@@ -4704,6 +4713,16 @@ build_template(
prebuilt->templ_contains_blob = FALSE;
+
+ /*
+ 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++) {
@@ -4717,6 +4736,8 @@ build_template(
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
@@ -4749,8 +4770,12 @@ build_template(
/* 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;
@@ -4805,6 +4830,13 @@ include_field:
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
+ }
if (field->stored_in_db) {
innodb_idx++;
}
@@ -4813,12 +4845,23 @@ skip_field:
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 = 0; i < n_requested_fields; i++) {
+ for (ulint i = do_idx_cond_push? prebuilt->n_index_fields : 0;
+ i < n_requested_fields; i++) {
templ = prebuilt->mysql_template + i;
-
templ->rec_field_no = templ->clust_rec_field_no;
}
}
@@ -5081,7 +5124,7 @@ no_commit:
/* Build the template used in converting quickly between
the two database formats */
- build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+ build_template(prebuilt, NULL, table, this, ROW_MYSQL_WHOLE_ROW);
}
innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -5620,6 +5663,8 @@ ha_innobase::index_end(void)
int error = 0;
DBUG_ENTER("index_end");
active_index=MAX_KEY;
+ in_range_check_pushed_down= FALSE;
+ ds_mrr.dsmrr_close();
DBUG_RETURN(error);
}
@@ -5780,7 +5825,8 @@ 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, ROW_MYSQL_REC_FIELDS);
+ build_template(prebuilt, user_thd, table, this,
+ ROW_MYSQL_REC_FIELDS);
}
if (key_ptr) {
@@ -5990,7 +6036,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, ROW_MYSQL_REC_FIELDS);
+ build_template(prebuilt, user_thd, table, this, ROW_MYSQL_REC_FIELDS);
DBUG_RETURN(0);
}
@@ -8118,6 +8164,7 @@ ha_innobase::info_low(
}
stats.check_time = 0;
+ stats.mrr_length_per_rec= ref_length + 8; // 8 = max(sizeof(void *));
if (stats.records == 0) {
stats.mean_rec_length = 0;
@@ -8321,7 +8368,7 @@ ha_innobase::check(
/* Build the template; we will use a dummy template
in index scans done in checking */
- build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+ build_template(prebuilt, NULL, table, this, ROW_MYSQL_WHOLE_ROW);
}
if (prebuilt->table->ibd_file_missing) {
@@ -8814,6 +8861,10 @@ 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;
break;
case HA_EXTRA_NO_KEYREAD:
prebuilt->read_just_key = 0;
@@ -8861,6 +8912,12 @@ ha_innobase::reset()
reset_template(prebuilt);
+ /* Reset index condition pushdown state */
+ pushed_idx_cond_keyno= MAX_KEY;
+ pushed_idx_cond= NULL;
+ 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. */
@@ -11973,3 +12030,91 @@ test_innobase_convert_name()
}
#endif /* UNIV_COMPILE_TEST_FUNCS */
+
+
+/****************************************************************************
+ * DS-MRR implementation
+ ***************************************************************************/
+
+/**
+ * Multi Range Read interface, DS-MRR calls
+ */
+
+int ha_innobase::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf)
+{
+ return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf);
+}
+
+int ha_innobase::multi_range_read_next(char **range_info)
+{
+ return ds_mrr.dsmrr_next(range_info);
+}
+
+ha_rows ha_innobase::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)
+{
+ /* See comments in ha_myisam::multi_range_read_info_const */
+ ds_mrr.init(this, table);
+
+ if (prebuilt->select_lock_type != LOCK_NONE)
+ *flags |= HA_MRR_USE_DEFAULT_IMPL;
+
+ ha_rows res= ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges,
+ bufsz, flags, cost);
+ return res;
+}
+
+ha_rows ha_innobase::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost)
+{
+ ds_mrr.init(this, table);
+ ha_rows res= ds_mrr.dsmrr_info(keyno, n_ranges, keys, key_parts, bufsz,
+ flags, cost);
+ return res;
+}
+
+
+
+/**
+ * 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 int index_cond_func_innodb(void *arg)
+{
+ ha_innobase *h= (ha_innobase*)arg;
+ if (h->end_range)
+ {
+ if (h->compare_key2(h->end_range) > 0)
+ return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
+ }
+ 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_NONE))
+ {
+ 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 */
+}
+
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index c60a5eae19e..8945ce95ee5 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -222,6 +222,24 @@ 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; }
+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(char **range_info);
+ 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);
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ DsMrr_impl ds_mrr;
+
+ Item *idx_cond_push(uint keyno, Item* idx_cond);
};
/* Some accessor functions which the InnoDB plugin needs, but which
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index 141f4beb81e..fbb9ee92a90 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -577,7 +577,9 @@ struct mysql_row_templ_struct {
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
+typedef int (*index_cond_func_t)(void *param);
/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
+
handle used within MySQL; these are used to save CPU time. */
struct row_prebuilt_struct {
@@ -775,6 +777,14 @@ struct row_prebuilt_struct {
/*----------------------*/
ulint magic_n2; /*!< this should be the same as
magic_n */
+ /*----------------------*/
+ index_cond_func_t idx_cond_func;/* Index Condition Pushdown function,
+ or NULL if there is none set */
+ void* idx_cond_func_arg;/* ICP function argument */
+ ulint n_index_fields; /* Number of fields at the start of
+ mysql_template. Valid only when using
+ ICP. */
+ /*----------------------*/
};
#define ROW_PREBUILT_FETCH_MAGIC_N 465765687
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index 82ad30bb390..4c6a91f3c69 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -2680,8 +2680,10 @@ row_sel_store_mysql_rec(
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) */
+ const ulint* offsets, /* in: array returned by
+ rec_get_offsets() */
+ ulint start_field_no, /* in: start from this field */
+ ulint end_field_no) /* in: end at this field */
{
mem_heap_t* extern_field_heap = NULL;
mem_heap_t* heap;
@@ -2697,7 +2699,7 @@ row_sel_store_mysql_rec(
prebuilt->blob_heap = NULL;
}
- for (i = 0; i < prebuilt->n_template; i++) {
+ for (i = start_field_no; i < end_field_no /* prebuilt->n_template */ ; i++) {
const mysql_row_templ_t*templ = prebuilt->mysql_template + i;
const byte* data;
@@ -3142,10 +3144,14 @@ row_sel_pop_cached_row_for_mysql(
/* Copy NULL bit of the current field from cached_rec
to buf */
if (templ->mysql_null_bit_mask) {
- buf[templ->mysql_null_byte_offset]
+ /*buf[templ->mysql_null_byte_offset]
^= (buf[templ->mysql_null_byte_offset]
^ cached_rec[templ->mysql_null_byte_offset])
- & (byte)templ->mysql_null_bit_mask;
+ & (byte)templ->mysql_null_bit_mask;*/
+ byte *null_byte= buf + templ->mysql_null_byte_offset;
+ (*null_byte)&= ~templ->mysql_null_bit_mask;
+ (*null_byte)|= cached_rec[templ->mysql_null_byte_offset] &
+ templ->mysql_null_bit_mask;
}
}
}
@@ -3182,7 +3188,10 @@ row_sel_push_cache_row_for_mysql(
ibool rec_clust, /*!< in: TRUE if rec is in the
clustered index instead of
prebuilt->index */
- const ulint* offsets) /*!< in: rec_get_offsets(rec) */
+ const ulint* offsets, /* in: rec_get_offsets() */
+ ulint start_field_no, /* in: start from this field */
+ byte* remainder_buf) /* in: if start_field_no !=0,
+ where to take prev fields */
{
byte* buf;
ulint i;
@@ -3216,12 +3225,44 @@ row_sel_push_cache_row_for_mysql(
prebuilt->mysql_row_len);
if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
- prebuilt->fetch_cache[
+ prebuilt->fetch_cache[
prebuilt->n_fetch_cached],
- prebuilt, rec, rec_clust, offsets))) {
+ 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);
+ }
+
+ offs = templ->mysql_col_offset;
+ memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached]
+ + offs,
+ remainder_buf + offs,
+ templ->mysql_col_len);
+ }
+ }
+
prebuilt->n_fetch_cached++;
return(TRUE);
}
@@ -3361,8 +3402,10 @@ row_search_for_mysql(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
+ ibool some_fields_in_buffer;
ibool table_lock_waited = FALSE;
ibool problematic_use = FALSE;
+ ibool get_clust_rec = 0;
rec_offs_init(offsets_);
@@ -3626,8 +3669,9 @@ row_search_for_mysql(
ut_ad(!rec_get_deleted_flag(rec, comp));
if (!row_sel_store_mysql_rec(buf, prebuilt,
- rec, FALSE,
- offsets)) {
+ rec, FALSE,
+ offsets, 0,
+ prebuilt->n_template)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such
@@ -4289,7 +4333,8 @@ no_gap_lock:
if (!lock_sec_rec_cons_read_sees(
rec, trx->read_view)) {
- goto requires_clust_rec;
+ get_clust_rec = TRUE;
+ goto idx_cond_check;
}
}
}
@@ -4334,12 +4379,36 @@ 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 == 0)
+ goto next_rec;
+ if (res == 2) {
+ err = DB_RECORD_NOT_FOUND;
+ goto idx_cond_failed;
+ }
+ }
+
/* 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:
/* We use a 'goto' to the preceding label if a consistent
read of a secondary index record requires us to look up old
versions of the associated clustered index record. */
@@ -4435,10 +4504,15 @@ requires_clust_rec:
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)) {
+ offsets,
+ some_fields_in_buffer?
+ prebuilt->n_index_fields : 0,
+ buf)) {
/* Only fresh inserts may contain incomplete
externally stored columns. Pretend that such
records do not exist. Such records may only be
@@ -4479,7 +4553,10 @@ requires_clust_rec:
if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
result_rec != rec,
- offsets)) {
+ offsets,
+ prebuilt->idx_cond_func?
+ prebuilt->n_index_fields: 0,
+ prebuilt->n_template)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such records do
@@ -4515,6 +4592,9 @@ got_row:
HANDLER command where the user can move the cursor with PREV or NEXT
even after a unique search. */
+ err = DB_SUCCESS;
+
+idx_cond_failed:
if (!unique_search_from_clust_index
|| prebuilt->select_lock_type != LOCK_NONE
|| prebuilt->used_in_HANDLER) {
@@ -4524,12 +4604,11 @@ got_row:
btr_pcur_store_position(pcur, &mtr);
}
- err = DB_SUCCESS;
-
goto normal_return;
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;